Fabulous Adventures In Coding
Eric Lippert is a principal developer on the C# compiler team. Learn more about Eric.
Here's a fragment of an email I received last week:
bigValue = 4294967295Wscript.Echo Hex(bigValue)I would like this to display FFFFFFFF, but instead get the error "Overflow: bigValue
What's up with that?
The Hex function only works on numbers which fit into a four-byte signed integer. Since it's signed, you can have negative numbers in there. Negative numbers are represented in hex by their complement. Therefore, the number that produces FFFFFFFF is -1, not 4294967295. Therefore, the questioner is going to have to learn to live with disappointment -- you can't always get what you want.
But of course, you should feel free to write your own Hex function that has whatever semantics you prefer. For instance, here’s one that will hexify an arbitrary double, and uses the innovation of a negative sign to indicate negative numbers. It uses some cheesy math tricks to repeatedly get the modulus of the number and shift the number down by a factor of 16 until there's nothing left:
Function MyHex(ByVal Number) Dim Sign Const HexChars = "0123456789ABCDEF" Sign = Sgn(Number) Number = Fix(Abs(CDbl(number))) If Number = 0 Then MyHex = "0" Exit Function End If While Number > 0 MyHex = Mid(HexChars, 1 + (Number - 16 * Fix(Number / 16)), 1) & MyHex Number = Fix(Number/16) WEnd If Sign = -1 Then MyHex = "-" & MyHexEnd Function All I ask is that you not call the function "Hex", and thereby overwrite the existing Hex function, unless you really, really want to and know what you're doing. Pulling shens like that can come back to haunt you later; I once spent about a day debugging an ASP page on MSN.com before I realized that it had it's own personal buggy implementation of InStr for some crazy reason, and someone else who modified the page did not realize that.
Just a quick note to anyone who might come across this, it's not always correct. I haven't figured out where it is going wrong yet, but:
MyHex(144616027440256497) returns 201C782C0679600 which is incorrect.
It should be 201C782C06795F1
My best guess is that it is a matter of rounding. I came across it when trying to work with MS Fax job ids.
That number is too big to fit into an integer, so it automatically goes into a double. It is too big to fit into a double without rounding.
Is there some reason why you didn't use "mod" and "\"?
Also, I always thought that the function name was used like a return statement, until I tried putting my own hex on my vbscript and got some unexpected results.
I guess I'll just have to read six years worth of blogs. :-)