salva/p5-Math-Int64 — pull request #6 by bulk88 (2014-01-21 09:53:32+00:00)
Title: MS Visual C things

I use a different algorithm for uint64_t to double on VC 6 than your code, which is how VC 2003 does its [brand new] uint64_t to double conversion

((NV)(I64)((x) & U64_CONST(0x7FFFFFFFFFFFFFFF)) + -(NV)(I64)((x) & U64_CONST(0x8000000000000000)))

vs your

static NV
u642nv(uint64_t u64) {
unsigned long h = u64 >> 32;
unsigned long l = u64 & 0xffffffff;
return ((((NV)65536) * ((NV)65536)) * h) + (NV)l;
}

which looks like in asm after optimizing by VC

static NV
u642nv(uint64_t u64) {
uint32_t hi = u64.HighPart;
u64.HighPart = 0;
return (double)hi * 4294967296.0 + (double)(signed __int64)u64;
}

I dont know which you prefer.

I also tested the nv2u64 code on various VCs, commenting out nv2u64 to a simple cast, VC 6 32 failed, VC 2003 32 failed, VC 2008 32 failed, VC 2008 x64 passed (with a 64 bit Perl of course). Because so many permutations failed, I didn't touch nv2u64, 1 permutation did pass, so consider that as an optimization, so maybe that bug you linked to in http://connect.microsoft.com/VisualStudio/feedback/details/270762/error-in-converting-double-to-unsigned-long-long was fixed for x64-only in atleast 2008 and newer and the fix can be #if'ed out.