Hex conversion to Int - Bug or My misunderstanding of VB.Net
Messages   Related Types
This message was discovered on microsoft.public.dotnet.languages.vb.
Responses highlighted in red are from those people who are likely to be able to contribute good, authoratitive information to this discussion. They include Microsoft employees, MVP's and others who IMHO contribute well to these kinds of discussions.
Post a new message to this list...

Dennis (VIP)
I get the following results:

Cint(&HC5798A2F) returns -981890513 as it should and

Clng("&HFFFFFFFFC5798A2F") returns -981890513 as it should.

However when using a string

Cint("(&HC5798A2F") returns an overflow exception.

Shouldn't the Cint return the same value for the same hex format number input?
--
Dennis in Houston
Reply to this message...
 
    
Fabricio (VIP)
You have one too many of these --> "("... try this Cint("&HC5798A2F")

-Fabricio

"Dennis" wrote:

[Original message clipped]

Reply to this message...
 
    
Dennis (VIP)
Yes, it was a typo but I get the overflow exception when I leave out the
extra (

"Fabricio" wrote:

[Original message clipped]

Reply to this message...
 
    
Fabricio (VIP)
I figured... just checking to see if you were still active on this thread :-)

Ok... here's the deal. It doesn't work because the hex number you're using,
C5798A2F, is too big for a 32-bit integer. The max value allowed is
2,147,483,647. Try a smaller number (string number) and see if that works.

-Fabricio
Click here to reveal e-mail address

"Dennis" wrote:

[Original message clipped]

Reply to this message...
 
    
Dennis (VIP)
Thanks to all who replied. Apparently, there is an inconsistency in the way
VB.Net treats conversions from literals to strings. For those who are
interested, below is what I ended up with and it seems to work:

Friend Function ConvByteArraytoInteger(ByVal b As Byte(), Optional ByVal ln
As Integer = 0, Optional ByVal sidx As Integer = 0) As Long
'converts a byte array to an integer starting at sidx in byte array
of length ln
Dim i As Integer
Dim k As Integer
Dim a As String
If ln = 0 Then ln = UBound(b) + 1
Dim h As StringBuilder = New StringBuilder(32)
k = sidx + ln - 1
For i = sidx To k
h.Append(Hex(b(i)).PadLeft(2, "0"c))
Next
If CInt("&H" & h.ToString.Substring(0, 1)) > &H7 Then
a = "&H" & h.ToString.PadLeft(16, "F"c)
Else
a = "&H" & h.ToString
End If
Return CLng(a)

End Function

"Dennis" wrote:

[Original message clipped]

Reply to this message...
 
    
Herfried K. Wagner [MVP] (VIP)
* =?Utf-8?B?RGVubmlz?= <Click here to reveal e-mail address> scripsit:
[Original message clipped]

The hexadecimal integer literal '&HC5798A2F' is treated as 'Int32':

\\\
MsgBox(&HC5798A2F.GetType().ToString()) ' 'System.Int32'.
///

> Clng("&HFFFFFFFFC5798A2F") returns -981890513 as it should.

FFFFFFFFC5798A2F(16) = 18446744072727661103(10)

This value cannot be stored in an 'Int64', so we interpret the number as
signed number. The sign bit is 1 which indicates a negative number, so
the result is the negative number mentioned above.

[Original message clipped]

'CInt' tries to parse the number. It doesn't try to parse an 'Int32',
but it parses an integer number. The result is the 'Int64' value
3313076783 which cannot be stored in an 'Int32'. As a consequence, an
exception is thrown.

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://dotnet.mvps.org/dotnet/faqs/>
Reply to this message...
 
    
David
On 2004-09-12, Dennis <Click here to reveal e-mail address> wrote:
[Original message clipped]

It's just a bug, it's not your misunderstanding of anything. My
favorite inconsistency here isn't the above, it's that

Dim i as Integer = CInt("&H" & Hex(someInteger))

can throw an exception. That tends to catch folks by surprise.

Technically, I suppose that one could make the argument that since
there's virtually no documentation on the correct behavior of CInt/CLng
and all the C??? functions in general, that almost any behavior could be
deemed officially "correct". But one would hope for consistency at
least, I would think.

Something useful though, if you need to do this, I'd strip off the "&H"
and use the Int32.Parse function, which is much more robust and much
more flexible.

Int32.Parse("C5798A2F", Globalization.NumberStyles.HexNumber)

correctly returns -981890513

Reply to this message...
 
    
Cor Ligthert
David,

[Original message clipped]

months later it's incredibly easy to forget that you've got some other
variable someplace while you know that is told in the Microsoft documents
that the advices convert class in VBNet are the VisualBasic convert methods
because they are normally more reliable and much more flexible and nobody
knows anymore why you did this.

In this case I just would make a workaround the problem as this.

Dim a As String = "&HC5798A2F".Replace("&H", "&HFFFFFFFF")
'Workaround Cint cannot handle negative hexa in the righ way strings
Dim b As Integer = CInt(a)
'And better before it is changed in future
Dim c As Long = CLng(a)
Dim d As Long = CInt(c)

I hope this helps?

Cor

Reply to this message...
 
    
Cor Ligthert
I never had this problem, so I tried it, however it is not generic, in my
opinion is that the fact with the routine beneath

\\\'workaround for negative hexastring to integer
Dim a As String = "&HC5798A2F".Replace("&H", "&HFFFFFFFF")
Dim b As Long = CLng(a)
Dim c As Integer
If b < 0 Then
c = CInt(b)
Else
c = CInt("&HC5798A2F")
End If
///

Reply to this message...
 
    
David
On 2004-09-12, Cor Ligthert <Click here to reveal e-mail address> wrote:
[Original message clipped]

What other variable? There are no other variables here.

I know you're trying to be snarky here, but it helps if your statement
makes sense.

Reply to this message...
 
    
Herfried K. Wagner [MVP] (VIP)
David,

* David <Click here to reveal e-mail address> scripsit:
[Original message clipped]

Visual Basic Language Reference -- Type Conversion Functions
<URL:http://msdn.microsoft.com/library/en-us/vblr7/html/vagrptypeconversion.asp>

.... says:

"
If the 'expression' passed to the function is outside the range of the
data type to which it is being converted, an error occurs.
"

I assume 'CInt' and 'CLng' work as follows (simplified):

1. Treat the string as representation of an unsigned integer number, if
no sign is specified. To do that, first parse the number into the
largest integer datatype, this is 'System.Int64'. For values larger
than 'Int64.MaxValue' treat the number as signed number to make it
smaller.

2. Then try to convert the 'Int64' to the destination datatype. If the
number does not fit into this datatype, an exception is thrown.

Sample:

\\\
Dim s As String = "&H" & Hex(Integer.MaxValue) ' "&H80000000".
Dim i As Integer = CInt(s) ' Overflow exception.
///

"&H80000000" is converted to an integer number (/not/ the 'Int32'
datatype). The result is 2147483648, which is a positive integer
number. This number is larger than the maximum value that can be stored
in an 'Int32', 2147483647. An exception is thrown.

I think this behavior is "by design", and I would have chosen this
behavior too when implementing 'C*' methods. String literals containing
string representations of integer values should always be treated as
representations of the largest possible integer datatype, independent
from the 'C*' method called on the string expression.

[Original message clipped]

I think the behavior is consistent. Parsing an integer number cannot be
compared with parsing a string literal representing an integer number.

[Original message clipped]

Mhm... For me, the VB.NET implementation is "correct".

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://dotnet.mvps.org/dotnet/faqs/>
Reply to this message...
 
    
David
On 2004-09-12, Herfried K. Wagner [MVP] <Click here to reveal e-mail address> wrote:
[Original message clipped]

Which is pretty vague, as we've seen. I can look at the actual behavior
of cint/clng and come up with something like the description you've made
below, but I don't think anyone could seriously maintain that they could
read the above and say with certainty what the behavior of clng/cint
would be when faced the the type of hex strings we're dealing with.

Which is no big deal for the most part. As I've said before, the real
spec to the VB language is the behavior of the compiler and libraries,
not the written documentation. And I don't think the written spec is
intended to be used in the same way an ANSI or ECMA spec is intended to
be used.

[Original message clipped]

Well, they seem awfully comparable to me. In fact, I strongly suspect
that if you asked most VB programmers to define the functions, that's
exactly the definition they'd give: that cint/clng convert the string
representation of a literal.

But there's no way this can be resolved, since there's no standard
measure of things like "consistency" and "elegant". The fact that
Integer-to-String and String-to-Integer don't round trip seems
problematic to me, but again, anybody can just say "they aren't
problematic to me" and I have no objective measure of the importance of
orthogonality to point to.

[Original message clipped]

That's nice. But "correctly" here referred to the fact that it fits the
needs of the OP, not to a more general statement about the language.

>
Reply to this message...
 
    
Herfried K. Wagner [MVP] (VIP)
* David <Click here to reveal e-mail address> scripsit:
[Original message clipped]

Yeah, with correct I mean that I am able to find an explanation of the
behavior, nothing more.

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://dotnet.mvps.org/dotnet/faqs/>
Reply to this message...
 
 
System.Globalization.NumberStyles
System.Int32
System.Int64
System.Text.StringBuilder




Ad
MBR BootFX
Best-of-breed application framework for .NET projects, developed by Matthew Baxter-Reynolds and MBR IT
 
 Copyright © Matthew Baxter-Reynolds 2001-2008. '.NET 247 Software Development Services' is a trading style of MBR IT Solutions Ltd.
Contact Us - Terms of Use - Privacy Policy - www.dotnet247.com