|
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.aspxsays "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-integerOne 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