in reply to Re^19: supporting quads on 32 bit Perl
in thread supporting quads on 32 bit Perl
This time I have compiled it with gcc -pedantic -std=c89 and removed all the nonstandard constructions...
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^21: supporting quads on 32 bit Perl
by bulk88 (Priest) on Jun 04, 2012 at 17:44 UTC | |
I'll try to update this node soon on what I think about the failed test XS wise if your not faster than me in fixing it. edit: given this XS Func called as which showed $u's &($u->sv_u.svu_rv->sv_any->xnv_u) in raw memory is $nv's &($nv->sv_any->xnv_u) in raw memory is ok lets try this result is IDK how many floating point digits are supposed to be shown. VS debugger says the NV slot in the SVNV is "1.8374686479671624e+019". == 0x43efe00000000000 == 100001111101111111000000000000000000000000000000000000000000000 chop off sign bit 00001111101111111000000000000000000000000000000000000000000000 chop off exponent (11 bits) 111111000000000000000000000000000000000000000000000 == 0x7E00000000000 0x7E00000000000 2 216 615 441 596 416 unsigned __int64 IDK. I'm not a math person. (two->sv_any->xnv_u.xnv_nv) > (2^53) true bool 0xff00_0000_0000_0000 is more than 2^53, it can't be held in a NV cleanly. 0xff00000000000000 > (2^53) true bool I don't have an infinite precision calc on hand, but 0xFF would be 64-8=56. Doubles store integers upto 2^53. There even is a Perl C const just for this, win32/config_H.vc#l4320 in perl.git. | [reply] [d/l] [select] |
by salva (Canon) on Jun 04, 2012 at 21:33 UTC | |
Removing the sign bit and the exponent and prepending the implicit 1., results in 1.1111111000000000000000000000000000000000000000000000. So the number is 0b1.1111111 * 2** (0b10000111110 - 1023) = 0b1.1111111 * 2 ** 63 = 0xff00_0000_0000_0000. The number can be represented precisely as an NV because its last bits are zero. The problem seems related to the MS compiler not converting correctly between NVs and uint64. Could you try the current GitHub version and post here the output from MSC.t? | [reply] [d/l] [select] |
by bulk88 (Priest) on Jun 04, 2012 at 22:50 UTC | |
Fixed the missing import. Thanks for the lesson in binary math. The hex to binary converter I used, I think I highlighted wrong for the copy in in the converter, and the first 0 was chopped off. From what I read about floating points a couple days ago, exact powers of 2 floating points suffer no rounding/precision loss, and thats what you are testing here right? I might update this post soon if I discover anything interesting. update I rewrote mu64_eqn. which in C is When the test fails, copied from watch window in hex and decimal Hmmm, in SvU64 _fto12 is a static linked piece of code in the DLL tossed in by the compiler, its not part of the CRT/not imported from the CRT DLL, its asm is Will need a while to look through this asm. puts 8000000000000000 in esp+10h, 0x8000000000000000 is what winds up in the uint64 in ::Int64. not 0xFF*. From x86 manual, "Integer Indefinite value (0x80000000) will be returned." from FISTP docs, "If the invalid operation exception is masked, the integer indefinite value is stored in the destination operand." which generated the 0x80* value, right after it executed, FPU status register was 0x3921 according to VS debugger. I don't understand LE/BE and the diagrams online of the fpu status register to decode that 0x3921. Update, the error is fpu invalid operation, and it has to do with the sign bit on the future int64. Given If d1 *= 128.0;, exception thrown/crash. If d1 *= 127.0;, then int64 0x7f00* is created, and no exception thrown. Not sure whose bug this is or how to fix it. I think its simply, fistp creates a signed int64, if the floating point higher than the max signed (0xFF00* has sign bit on for signed), exception thrown. Update, MSVC bug! https://connect.microsoft.com/VisualStudio/feedback/details/106531/co | [reply] [d/l] [select] |
by salva (Canon) on Jun 05, 2012 at 09:40 UTC | |
by bulk88 (Priest) on Jun 05, 2012 at 16:33 UTC | |
| |