Can't create uint32 values outside int32 range?

  • Thread starter Alex K. Angelopoulos [MVP]
  • Start date
A

Alex K. Angelopoulos [MVP]

Can anyone suggest a simple way to create a UInt32 value such as 0x80000002
_nicely_?

If you try the direct approach by supplying the hex, it gets created as an
Int32 and then falls outside the proper range:
PS> [uint32]0x80000002
Cannot convert value "-2147483646" to type "System.UInt32". Error:
"Value was either too large or too small for a UInt32."
At line:1 char:9
+ [uint32]0 <<<< x80000002

There are ways around this by doing everything from a numeric parse to
something silly like this:

[UInt32]$hklm = 0x7999999 + 3

It would be nice if this worked directly.
 

My Computer

A

Alex K. Angelopoulos [MVP]

Error correcttion plus demo of another way that the hex handling is buggy..

"Alex K. Angelopoulos [MVP]" <[email protected]> wrote in message
news:[email protected]

> [UInt32]$hklm = 0x7999999 + 3

I dropped a 9 here; this should be
[UInt32]$hklm = 0x79999999 + 3


Also, you can see the oddities in this if you try to perform math that
includes a hex value extending outside the standard positive int32 range:

PS> 0x80000002 - 0x79999999
-4187593111

The result should actually be 3.
 

My Computer

A

Alex K. Angelopoulos [MVP]

OK, I really should stop posting before my morning coffee. My 0x79999999
values should all be 0x7FFFFFFF. ;)
 

My Computer

O

/\\/\\o\\/\\/

I'm a bit confused the values do not look the same:

PoSH>([UInt32]0x7999999 + 3)
127506844

Si I can do this with that Number

PoSH>[UInt32]0x799999C
127506844

PoSH>[uint32]::TryParse(([uint32](0x80000002).tostring("X")),[ref]$u)
True
PoSH>$u
80000002

PoSH>[uint32]$u
80000002

Greetings /\/\o\/\/

Alex K. Angelopoulos [MVP] wrote:
> Can anyone suggest a simple way to create a UInt32 value such as 0x80000002
> _nicely_?
>
> If you try the direct approach by supplying the hex, it gets created as an
> Int32 and then falls outside the proper range:
> PS> [uint32]0x80000002
> Cannot convert value "-2147483646" to type "System.UInt32". Error:
> "Value was either too large or too small for a UInt32."
> At line:1 char:9
> + [uint32]0 <<<< x80000002
>
> There are ways around this by doing everything from a numeric parse to
> something silly like this:
>
> [UInt32]$hklm = 0x7999999 + 3
>
> It would be nice if this worked directly.
>
>
 

My Computer

O

/\\/\\o\\/\\/

After some experimenting I came to this :

PoSH> [System.BitConverter]::toUint32( ([System.BitConverter]::GetBytes(0x80000002)),0 )
2147483650

But I could not make it into a function as every time $number could get casted to :
-2147483646

Function get-Uint32 ([string]$number) {
[System.BitConverter]::toUint32( ([System.BitConverter]::GetBytes($number)),0 )
}

then I did get it the hex is always translated to an INT before we do anything :

PoSH>0x80000002 | gm


TypeName: System.Int32

so you need to give it to the Uint as a string :

PoSH>[Uint32]"0x80000002"
2147483650


Greetings /\/\o\/\/


/\/\o\/\/ wrote:
> I'm a bit confused the values do not look the same:
>
> PoSH>([UInt32]0x7999999 + 3)
> 127506844
>
> Si I can do this with that Number
>
> PoSH>[UInt32]0x799999C
> 127506844
>
> PoSH>[uint32]::TryParse(([uint32](0x80000002).tostring("X")),[ref]$u)
> True
> PoSH>$u
> 80000002
>
> PoSH>[uint32]$u
> 80000002
>
> Greetings /\/\o\/\/
>
> Alex K. Angelopoulos [MVP] wrote:
>> Can anyone suggest a simple way to create a UInt32 value such as
>> 0x80000002 _nicely_?
>>
>> If you try the direct approach by supplying the hex, it gets created
>> as an Int32 and then falls outside the proper range:
>> PS> [uint32]0x80000002
>> Cannot convert value "-2147483646" to type "System.UInt32". Error:
>> "Value was either too large or too small for a UInt32."
>> At line:1 char:9
>> + [uint32]0 <<<< x80000002
>>
>> There are ways around this by doing everything from a numeric parse to
>> something silly like this:
>>
>> [UInt32]$hklm = 0x7999999 + 3
>>
>> It would be nice if this worked directly.
>>
 

My Computer

A

Alex K. Angelopoulos [MVP]

"/\/\o\/\/" <[email protected]> wrote in message
news:[email protected]

> then I did get it the hex is always translated to an INT before we do
> anything :


That's a nice bit of simple-but-brilliant reasoning - submit it as a string
for constants you need to set.

> PoSH>[Uint32]"0x80000002"


This still leaves the problem of user-supplied values, but that can be
solved using the -f operator.

PS> $v = 0x80000002
PS> $v
-2147483646
PS> $v1 = "0x{0:x}" -f $v
PS> $v1
0x80000002
PS> [UInt32]$v2 = $v1
PS> $v2
2147483650

So we can actually turn this into a simple one-liner:
PS> function To-UInt32{[UInt32]("0x{0:x}" -f $args[0])}
PS> To-UInt32 0x80000002
2147483650
 

My Computer

O

/\\/\\o\\/\\/

2 other nice ones :

PoSH>[Uint32]::Parse("80000002",'HexNumber')
2147483650

PoSH>[Uint32]$u = 0
PoSH>[Uint32]::tryParse("80000002",'HexNumber',([Globalization.NumberFormatInfo]::get_CurrentInfo()),[ref]$U)
True
PoSH>$U
2147483650

You can format it for cultures I took the current :

[Globalization.NumberFormatInfo]::get_CurrentInfo()

gr /\/\o\/\/


Alex K. Angelopoulos [MVP] wrote:
> "/\/\o\/\/" <[email protected]> wrote in message
> news:[email protected]
>
>> then I did get it the hex is always translated to an INT before we do
>> anything :

>
> That's a nice bit of simple-but-brilliant reasoning - submit it as a string
> for constants you need to set.
>
>> PoSH>[Uint32]"0x80000002"

>
> This still leaves the problem of user-supplied values, but that can be
> solved using the -f operator.
>
> PS> $v = 0x80000002
> PS> $v
> -2147483646
> PS> $v1 = "0x{0:x}" -f $v
> PS> $v1
> 0x80000002
> PS> [UInt32]$v2 = $v1
> PS> $v2
> 2147483650
>
> So we can actually turn this into a simple one-liner:
> PS> function To-UInt32{[UInt32]("0x{0:x}" -f $args[0])}
> PS> To-UInt32 0x80000002
> 2147483650
>
>
 

My Computer

K

Keith Hill [MVP]

"Alex K. Angelopoulos [MVP]" <[email protected]> wrote in message
news:[email protected]
> Can anyone suggest a simple way to create a UInt32 value such as
> 0x80000002 _nicely_?


PoSH> 0x80000002L

or if you really must have it as an UINT32:

PoSH> [uint32]0x80000002L

--
Keith
 

My Computer

B

Bruce Payette [MSFT]

Version 1 of PowerShell doen't natively support unsigned types. Keith's
suggestion is a probably the best workaround for the time being.

-bruce

--
Bruce Payette [MSFT]
Windows PowerShell Technical Lead
Microsoft Corporation
This posting is provided "AS IS" with no warranties, and confers no rights.
Visit the Windows PowerShell Team blog at:
http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:
http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx


"Keith Hill [MVP]" <[email protected]> wrote in message
news:[email protected]
>
> "Alex K. Angelopoulos [MVP]" <[email protected]> wrote in message
> news:[email protected]
>> Can anyone suggest a simple way to create a UInt32 value such as
>> 0x80000002 _nicely_?

>
> PoSH> 0x80000002L
>
> or if you really must have it as an UINT32:
>
> PoSH> [uint32]0x80000002L
>
> --
> Keith
>
 

My Computer

K

Keith Hill [MVP]

"Bruce Payette [MSFT]" <[email protected]> wrote in message
news:[email protected]
> Version 1 of PowerShell doen't natively support unsigned types. Keith's
> suggestion is a probably the best workaround for the time being.
>


BTW is the use of "L" to promote an integer literal to Int64 documented? I
just thought of how I would do this in C# and tried it in PoSH and it
worked! I was very impressed - if not a bit surprised. :-)

--
Keith
 

My Computer

A

Alex K. Angelopoulos [MVP]

It's part of the 'true' grammar, although it isn't currently included in the
draft grammar doc:
http://blogs.msdn.com/powershell/archive/2006/05/10/594535.aspx

I did some experimenting with single-character suffixes just to check, and
it looks like the only other explicit typing character used is d, which is
used for decimal.

I think having 1-2 character suffixes for specific purposes is useful, but
we need to be careful to make it VERY clear that literals like that are
PS-specific - there's no glide-sloping these since the only one used the
same way at present is L for long.



"Keith Hill [MVP]" <[email protected]> wrote in message
news:[email protected]
> "Bruce Payette [MSFT]" <[email protected]> wrote in message
> news:[email protected]
>> Version 1 of PowerShell doen't natively support unsigned types. Keith's
>> suggestion is a probably the best workaround for the time being.
>>

>
> BTW is the use of "L" to promote an integer literal to Int64 documented?
> I just thought of how I would do this in C# and tried it in PoSH and it
> worked! I was very impressed - if not a bit surprised. :-)
>
> --
> Keith
>
 

My Computer

K

Keith Hill [MVP]

"Alex K. Angelopoulos [MVP]" <[email protected]> wrote in message
news:%[email protected]
> I did some experimenting with single-character suffixes just to check, and
> it looks like the only other explicit typing character used is d, which is
> used for decimal.

That's unfortunate since C# uses "M" for this.

> I think having 1-2 character suffixes for specific purposes is useful, but
> we need to be careful to make it VERY clear that literals like that are
> PS-specific - there's no glide-sloping these since the only one used the
> same way at present is L for long.

That wouldn't be true if PoSH switched to use "M" for the System.Decimal
type.

--
Keith
 

My Computer

A

Alex K. Angelopoulos [MVP]

"Keith Hill [MVP]" <[email protected]> wrote in message
news:[email protected]
> "Alex K. Angelopoulos [MVP]" <[email protected]> wrote in message
> news:%[email protected]
>> I did some experimenting with single-character suffixes just to check,
>> and it looks like the only other explicit typing character used is d,
>> which is used for decimal.

> That's unfortunate since C# uses "M" for this.
>
>> I think having 1-2 character suffixes for specific purposes is useful,
>> but we need to be careful to make it VERY clear that literals like that
>> are PS-specific - there's no glide-sloping these since the only one used
>> the same way at present is L for long.

> That wouldn't be true if PoSH switched to use "M" for the System.Decimal
> type.


But then we'd have to dump k and g. :)

I don't mind treating these alphabetic suffixes as domain-specific
solutions, though. If we wanted to add U for uint32 and UL for uint64, I'd
be quite happy about it.
 

My Computer

Top