-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
It contains the following code:
if (AbsFitsIntoUint64(bigint)) {
double absolute_value = static_cast<double>(AbsToUint64(bigint));
double result = bigint.IsNegative() ? -absolute_value : absolute_value;
return Double::New(result);
}
all previously supported systems agreed on what they do when compiling static_cast<double>(uint64_value) however MSVC 2010 on Windows 64 does not agree with other systems. Here is a demo:
if defined(_MSC_VER)
include <stdint.h>
define PRIu64 "I64u"
else
ifndef __STDC_FORMAT_MACROS
define __STDC_FORMAT_MACROS
endif
include <inttypes.h>
endif
include <cstdio>
double convert(uint64_t x) {
return static_cast<double>(x);
}
uint64_t bitcast(double x) {
return (uint64_t)&x;
}
int main(int argc, char* argv[]) {
const uint64_t a = 12345678901234567891ULL;
const double b = convert(a);
const uint64_t c = bitcast(b);
const uint64_t d = 4892433759222981601ULL;
printf("{%" PRIu64 " => %lf (%" PRIu64 ")} %s %" PRIu64 "\n",
a, b, c, c == d ? "==" : "!=", d);
return 0;
}
∮ g++ -m32 -o test test.cc
∮ ./test
{12345678901234567891 => 12345678901234567168.000000 (4892433759222981601)} == 4892433759222981601
∮ g++ -m64 -o test test.cc
∮ ./test
{12345678901234567891 => 12345678901234567168.000000 (4892433759222981601)} == 4892433759222981601
On MSVC x86
D:\src\temp3>cl /nologo test.cc
D:\src\temp3>test.exe
{12345678901234567891 => 12345678901234567000.000000� (4892433759222981601)} == 4892433759222981601
On MSVC x64
D:\src\temp3>cl /nologo test.cc
D:\src\temp3>test.exe
{12345678901234567891 => 12345678901234569000.000000 (4892433759222981602)} != 4892433759222981601
This difference causes corelib/big_integer_vm_test to fail on Windows x64. I am going to mark this failure as expected for now but we need to have a work-around for this incompatibility.
Activity
lrhn commentedon Jun 5, 2014
We should be aware that MSVC x86 has a different double->string conversion than g++, if we use the system's conversion.
The x64 result is .. bad. It is not the nearest double to the original integer value. I'm surprised that it is the x64 version that differs, since I should be able to uuse a SSE2 instruction that does the right thing. Unless its FPU rounding flag is set to round up for some reason.
mraleph commentedon Jun 6, 2014
I landed the fix in r37078 by using the same code that GCC generates to match the rounding.
Added Fixed label.