acute blog in an obtuse world

Friday, July 20, 2007

x == y for very large values of x and y - part deux

OK, continuing from the previous post, why does eq equal true when comparing numbers that are obviously not equivalent?

Well... looking at the numbers that are used, you might take a hint from their magnitude: they are really big numbers. The equivalent script using decimal numbers would look like this:

var n = 18014398509481984;

var m = 18014398509481986;

var eq = (m == n);

The puzzle script with decimal-encoded numbers. Yes... eq == true what's up?

Yes, the numbers are big... but not so big they won't fit in a 64-bit integer. Looking back at the previous post's script, notice that the bigger of the two numbers is 0x0040000000000002; the largest 64-bit integer would be expressed as all sixteen hex digits with a value of F. It's not a sign issue, since the MSB of isn't set for either number.


So JScript must be storing the numbers internally using something other than a 64-bit integer to store the values. In fact, it uses the VARIANT data type. A VARIANT is a discriminated union that can hold just about any common data type--very useful for 'typeless' languages like JScript. A modern (post-Windows 2000) VARIANT can hold a 64-bit integer (a.k.a long long, or VT_I8 in VARIANT-speak), but JScript 5.6 doesn't use it, probably for legacy compatibility reasons.

Today's Puzzle

So now, another puzzle: what VARIANT type does JScript use to hold these large integers? (hint: it's not VT_I4!)

Tuesday, July 17, 2007

x == y for very large values of x and y

Lately, I've been doing some work that has required me to look very closely at the way scripting languages represent scalar values internally and how they are represented when passed to and from a COM server.

The results are interesting, but the process of collection was not interesting at all, so if you need this information too, maybe I can save you some pain.

OK, what am I talking about?

Here's a little JScript puzzle to illustrate:

The Puzzle

var n = 0x0040000000000000;

var m = 0x0040000000000002;

var eq = (m == n);

If you run the code, what will the value of eq be?

The Answer

What's your answer?

You probably smell a rat here and answered "true." And you were right! But why were you right? Stay tuned for the details...