lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On 4/15/2014 2:13 PM, Roberto Ierusalimschy wrote:
Can someone with more experience with MS check this?

Consider the next program:

/*---------------------------------------------------*/
#include <stdio.h>
#include <windows.h>

int main (void) {
   unsigned __int64 x = 0xFFFFFFFFFFFFFFFFL;
   double d = (double)x * 0.9;
   unsigned __int64 y = (unsigned __int64)d;
   printf("%I64x %I64x  %g\n", x, y, d);
   return 0;
}
/*---------------------------------------------------*/

'x' is the maximum value allowed for its type, 2^64-1. Then it is
converted to double, and rounded to 2^64. The product with 0.9 gives
a number "much" smaller than 2^64 (~1.6e19 versus ~1.8e19) which,
when rounded, clearly fits in 'y'. However, when I run this program
in Visual Studio 2010, it prints 'y' as 8000000000000000, signaling
an overflow.

(I need this casting, so that math.random(math.mininteger, math.maxinteger)
can give its full range of values.)

Thanks in advance,

-- Roberto



Hello.

This caught my curiosity so I did some reading...

The following MSDN page:

    Conversions from Floating-Point Types
http://msdn.microsoft.com/en-us/library/d3d6fhea%28v=vs.100%29.aspx

says "A floating value is converted to an integral value by first converting to a long, then from the long value to the specific integral value. The decimal portion of the floating value is discarded in the conversion to a long. If the result is still too large to fit into a long, the result of the conversion is undefined. " Unfortunately the page doesn't mention the __int64 type specifically, but perhaps it is handled similarly.


The following Stack Overflow question may also be relevant:

    Safe conversion from double to unsigned 64 bit integer
http://stackoverflow.com/questions/3332440/safe-conversion-from-double-to-unsigned-64-bit-integer

One of the answers quotes a Microsoft source saying "Our floating-point to integer conversions are always done to a signed integer...."


The following discussion threads also discuss the issue but I don't know that they add much to the above.

    Error converting double to unsigned __int64
http://social.msdn.microsoft.com/Forums/vstudio/en-US/d6703e17-a79b-4dbb-8760-bdb7f31dade0/error-converting-double-to-unsigned-int64?forum=vcgeneral

    C++ unsigned __int64 to/from double conversions
http://www.gamedev.net/topic/591975-c-unsigned-__int64-tofrom-double-conversions/


Hope that's helpful.

--
Edward Berner