http://www.perlmonks.org?node_id=974421


in reply to Re^23: supporting quads on 32 bit Perl
in thread supporting quads on 32 bit Perl

From what I read about floating points a couple days ago, exact powers of 2 floating points suffer no rounding/precision loss
Well, not exactly. IEEE 754 double-precision floats can represent precisely any number with 53 binary digits (and that covers all the integers up to 2**53 and all the powers of two).

It is the same as using decimal scientific notation. For instance, with a number of the form XXXeXX you can represent precisely any integer between 0 an 999, but then you can also represent precisely 5670, 56700, 567000, 5670000, etc.

The reason of the MSC.t is that at some point, one of the errors on the compilation logs from the ActiveState build server was:

Int64.xs(340) : error C2520: conversion from unsigned __int64 to doubl +e not implemented, use signed __int64
There were other places where NVs where converted to uint64 and back even if the compiler didn't spot them, so I added the MSC.t tests to ensure that they were correctly handled... but the thing is that they are not! (see also this).

Now, as a work around, I have implemented my own NV->uint64 conversion that will be used instead of the default one when the module is compiled by any MS compiler.

Could you test the git version again?

Replies are listed 'Best First'.
Re^25: supporting quads on 32 bit Perl
by bulk88 (Priest) on Jun 05, 2012 at 16:33 UTC
    Its
    #if ((defined _MSC_VER) || (defined INT64_MY_NV2U64))
    not
    #if ((defined _MSV_VER) || (defined INT64_MY_NV2U64))
    Typo i kno.

    After fixing that.
    C:\Documents and Settings\Owner\Desktop\cpan libs\salva-p5-Math-Int64- +09023f2>nm ake clean & perl makefile.pl & nmake install & nmake test Microsoft (R) Program Maintenance Utility Version 7.10.3077 Copyright (C) Microsoft Corporation. All rights reserved. C:\perl512\bin\perl.exe -MExtUtils::Command -e "rm_f" -- *.li +b core co re.[0-9] core.[0-9][0-9] Int64.bso blib\arch\auto\Math\Int64\extralib +s.ld pm_t o_blib.ts core.[0-9][0-9][0-9][0-9] Int64.x Int64.bs perl.exe tmon.o +ut blib\a rch\auto\Math\Int64\extralibs.all *.obj pm_to_blib blibdirs.ts core. +[0-9][0-9] [0-9][0-9][0-9] *perl.core core.*perl.*.? Makefile.aperl perl Int64. +def core. [0-9][0-9][0-9] mon.out libInt64.def perlmain.c perl.exe so_location +s Int64.c Int64.exp C:\perl512\bin\perl.exe -MExtUtils::Command -e "rm_rf" -- *.p +db blib C:\perl512\bin\perl.exe -MExtUtils::Command -e "mv" -- Makefil +e Makefile .old > NUL Using NV backend Checking if your kit is complete... Looks good Writing Makefile for Math::Int64 Microsoft (R) Program Maintenance Utility Version 7.10.3077 Copyright (C) Microsoft Corporation. All rights reserved. cp lib/Math/Int64.pm blib\lib\Math\Int64.pm cp lib/Math/Int64/die_on_overflow.pm blib\lib\Math\Int64\die_on_overfl +ow.pm cp lib/Math/Int64/native_if_available.pm blib\lib\Math\Int64\native_if +_available .pm C:\perl512\bin\perl.exe C:\perl512\lib\ExtUtils\xsubpp -nolin +enumbers -typemap C:\perl512\lib\ExtUtils\typemap Int64.xs > Int64.xsc && C:\p +erl512\bin \perl.exe -MExtUtils::Command -e "mv" -- Int64.xsc Int64.c cl -c -I. -nologo -GF -W3 -Od -MD -Zi -DDEBUGGING -DWIN32 -D +_CONSOLE - DNO_STRICT -DHAVE_DES_FCRYPT -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_S +YS -DUSE_P ERLIO -Od -MD -Zi -DDEBUGGING -DVERSION=\"0.24\" -DXS_VERSION=\"0. +24\" "-IC :\perl512\lib\CORE" -DINT64_BACKEND_NV Int64.c Int64.c Int64.c(69) : warning C4244: 'initializing' : conversion from 'NV' to +'uint64_t' , possible loss of data Int64.c(70) : warning C4244: 'initializing' : conversion from 'NV' to +'uint64_t' , possible loss of data Int64.c(292) : warning C4244: 'return' : conversion from 'NV' to 'int6 +4_t', poss ible loss of data Int64.c(381) : warning C4244: 'initializing' : conversion from 'int64_ +t' to 'IV' , possible loss of data Int64.c(386) : warning C4244: 'initializing' : conversion from 'int64_ +t' to 'UV' , possible loss of data Int64.c(390) : warning C4244: 'function' : conversion from 'int64_t' t +o 'const N V', possible loss of data Int64.c(396) : warning C4244: 'initializing' : conversion from 'uint64 +_t' to 'UV ', possible loss of data Int64.c(399) : warning C4244: 'function' : conversion from 'uint64_t' +to 'const NV', possible loss of data Int64.c(411) : warning C4244: 'initializing' : conversion from 'uint64 +_t' to 'ch ar', possible loss of data Int64.c(673) : warning C4244: 'function' : conversion from 'int64_t' t +o 'const I V', possible loss of data Int64.c(709) : warning C4244: 'function' : conversion from 'uint64_t' +to 'const UV', possible loss of data Int64.c(740) : warning C4244: '=' : conversion from 'int64_t' to 'char +', possibl e loss of data Int64.c(770) : warning C4244: '=' : conversion from 'uint64_t' to 'cha +r', possib le loss of data Int64.c(1017) : warning C4244: 'function' : conversion from 'uint64_t' + to 'const IV', possible loss of data Int64.c(1047) : warning C4244: 'function' : conversion from 'uint64_t' + to 'const UV', possible loss of data Int64.c(1070) : warning C4244: 'function' : conversion from 'uint64_t' + to 'const IV', possible loss of data Int64.c(1093) : warning C4244: 'function' : conversion from 'uint64_t' + to 'const UV', possible loss of data Int64.c(1116) : warning C4244: 'function' : conversion from 'int64_t' +to 'const IV', possible loss of data Int64.c(1139) : warning C4244: 'function' : conversion from 'uint64_t' + to 'const IV', possible loss of data Int64.c(1203) : warning C4101: 'rev' : unreferenced local variable Int64.c(1202) : warning C4101: 'other' : unreferenced local variable Int64.c(1229) : warning C4101: 'rev' : unreferenced local variable Int64.c(1228) : warning C4101: 'other' : unreferenced local variable Int64.c(1634) : warning C4101: 'rev' : unreferenced local variable Int64.c(1659) : warning C4101: 'rev' : unreferenced local variable Int64.c(1917) : warning C4101: 'rev' : unreferenced local variable Int64.c(1916) : warning C4101: 'other' : unreferenced local variable Int64.c(1940) : warning C4101: 'rev' : unreferenced local variable Int64.c(1939) : warning C4101: 'other' : unreferenced local variable Int64.c(1963) : warning C4101: 'rev' : unreferenced local variable Int64.c(1962) : warning C4101: 'other' : unreferenced local variable Int64.c(1986) : warning C4101: 'rev' : unreferenced local variable Int64.c(1985) : warning C4101: 'other' : unreferenced local variable Int64.c(2009) : warning C4101: 'rev' : unreferenced local variable Int64.c(2008) : warning C4101: 'other' : unreferenced local variable Int64.c(2032) : warning C4101: 'rev' : unreferenced local variable Int64.c(2031) : warning C4101: 'other' : unreferenced local variable Int64.c(2055) : warning C4101: 'rev' : unreferenced local variable Int64.c(2054) : warning C4101: 'other' : unreferenced local variable Int64.c(2078) : warning C4101: 'rev' : unreferenced local variable Int64.c(2077) : warning C4101: 'other' : unreferenced local variable Int64.c(2103) : warning C4101: 'rev' : unreferenced local variable Int64.c(2102) : warning C4101: 'other' : unreferenced local variable Int64.c(2489) : warning C4101: 'rev' : unreferenced local variable Int64.c(2514) : warning C4101: 'rev' : unreferenced local variable Int64.c(2772) : warning C4101: 'rev' : unreferenced local variable Int64.c(2771) : warning C4101: 'other' : unreferenced local variable Int64.c(2795) : warning C4101: 'rev' : unreferenced local variable Int64.c(2794) : warning C4101: 'other' : unreferenced local variable Int64.c(2818) : warning C4101: 'rev' : unreferenced local variable Int64.c(2817) : warning C4101: 'other' : unreferenced local variable Int64.c(2841) : warning C4101: 'rev' : unreferenced local variable Int64.c(2840) : warning C4101: 'other' : unreferenced local variable Int64.c(2864) : warning C4101: 'rev' : unreferenced local variable Int64.c(2863) : warning C4101: 'other' : unreferenced local variable Int64.c(2887) : warning C4101: 'rev' : unreferenced local variable Int64.c(2886) : warning C4101: 'other' : unreferenced local variable Int64.c(2910) : warning C4101: 'rev' : unreferenced local variable Int64.c(2909) : warning C4101: 'other' : unreferenced local variable c:\documents and settings\owner\desktop\cpan libs\salva-p5-math-int64- +09023f2\in t64.c(206) : warning C4715: 'SvSI64' : not all control paths return a +value c:\documents and settings\owner\desktop\cpan libs\salva-p5-math-int64- +09023f2\in t64.c(216) : warning C4715: 'SvSU64' : not all control paths return a +value Running Mkbootstrap for Math::Int64 () C:\perl512\bin\perl.exe -MExtUtils::Command -e "chmod" -- 644 +Int64.bs C:\perl512\bin\perl.exe -MExtUtils::Mksymlists -e "Mksymlists +('NAME'=>\ "Math::Int64\", 'DLBASE' => 'Int64', 'DL_FUNCS' => { }, 'FUNCLIST' => + [], 'IMPO RTS' => { }, 'DL_VARS' => []);" link -out:blib\arch\auto\Math\Int64\Int64.dll -dll -nologo -no +defaultlib -debug -libpath:"c:\perl512\lib\CORE" -machine:x86 Int64.obj C:\p +erl512\lib \CORE\perl512.lib oldnames.lib kernel32.lib user32.lib gdi32.lib winsp +ool.lib c omdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32. +lib uuid.l ib ws2_32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib c +omctl32.li b msvcrt.lib -def:Int64.def Creating library blib\arch\auto\Math\Int64\Int64.lib and object bli +b\arch\aut o\Math\Int64\Int64.exp if exist blib\arch\auto\Math\Int64\Int64.dll.manifest mt -nolo +go -manife st blib\arch\auto\Math\Int64\Int64.dll.manifest -outputresource:blib\a +rch\auto\M ath\Int64\Int64.dll;2 if exist blib\arch\auto\Math\Int64\Int64.dll.manifest del blib +\arch\auto \Math\Int64\Int64.dll.manifest C:\perl512\bin\perl.exe -MExtUtils::Command -e "chmod" -- 755 +blib\arch\ auto\Math\Int64\Int64.dll C:\perl512\bin\perl.exe -MExtUtils::Command -e "cp" -- Int64.b +s blib\arc h\auto\Math\Int64\Int64.bs C:\perl512\bin\perl.exe -MExtUtils::Command -e "chmod" -- 644 +blib\arch\ auto\Math\Int64\Int64.bs Files found in blib\arch: installing files in blib\lib into architectu +re depende nt library tree Installing C:\perl512\site\lib\auto\Math\Int64\Int64.dll Installing C:\perl512\site\lib\auto\Math\Int64\Int64.exp Installing C:\perl512\site\lib\auto\Math\Int64\Int64.ilk Installing C:\perl512\site\lib\auto\Math\Int64\Int64.lib Installing C:\perl512\site\lib\auto\Math\Int64\Int64.pdb Appending installation info to c:\perl512\lib/perllocal.pod Microsoft (R) Program Maintenance Utility Version 7.10.3077 Copyright (C) Microsoft Corporation. All rights reserved. C:\perl512\bin\perl.exe "-MExtUtils::Command::MM" "-e" "test_h +arness(0, 'blib\lib', 'blib\arch')" t/*.t t/as_int64.t ............ ok t/die_on_overflow.t ..... ok t/Math-Int64-Native.t ... ok t/Math-Int64.t .......... ok t/Math-UInt64-Native.t .. ok t/Math-UInt64.t ......... ok t/MSC.t ................. ok t/pods.t ................ skipped: Only the author needs to check that + POD docs are right All tests successful. Files=8, Tests=256, 1 wallclock secs ( 0.19 usr + 0.03 sys = 0.22 C +PU) Result: PASS C:\Documents and Settings\Owner\Desktop\cpan libs\salva-p5-Math-Int64- +09023f2>
    I guess we are done then unless you can think of more tests or something you want to try. I embedded it into my module a couple days ago and wrote a *small* test suite for the Math::Int64 part and everything works fine so the build/module tests were the only problems. I decided to NOT use the C API of Math::Int64 and instead used the something_*native*_something Perl subs and called them from XS for stability reasons (although Math::In64 is 4-5 years old, so some will argue all of its API is stable) and also to avoid loading Math::Int64 unless the caller/user does it. Now time for my opinion. I see you versioned the C API, and the version numbers of the C API aren't the mainline module's numbers (good, otherwise a nightmare matching packager build version numbers), and you didn't go the DLL linking route (nightmareish if the dlls are renamed/PAR, or duplicate names exist in the path, someone will say using OS DLL linking is much more efficient than doing it through Perl packages and hashs). You did a better design than Perl TK's C function import/exporter. In Perl TK, an IV with a pointer to a C static struct of function pointers is saved in Perl TK's package as a global. There is poor versioning, the struct does have a length of the struct as the 1st member, and its checked in the client against what the client's Perl TK headers said the struct size was supposed to be. The problem is if the order of the function pointers is changed or they are renamed, but the total length wasn't changed, a crash results. With your system, order is irrelevant, and if a single C function name was removed or changed, an error is thrown. Thats good. I've also realize that most of the build problems were because you wrote ::Int64 in GNUC, not C jkjk. I assume ::Int64 has worked from day 1 on Strawberry Perl. I also tested the latest github (same as above with msc_ver mistake), with Strawberry Perl, nothing to note.
    C:\Documents and Settings\Owner\Desktop\cpan libs\salva-p5-Math-Int64- +09023f2>pe rl makefile.pl & dmake install & dmake test Using NV backend Writing Makefile for Math::Int64 Skip blib\lib\Math\Int64.pm (unchanged) Skip blib\lib\Math\Int64\die_on_overflow.pm (unchanged) Skip blib\lib\Math\Int64\native_if_available.pm (unchanged) gcc -c -I. -s -O2 -DWIN32 -DHAVE_DES_FCRYPT -DUSE_SITECUSTOMIZE - +DPERL_IMPL ICIT_CONTEXT -DPERL_IMPLICIT_SYS -fno-strict-aliasing -mms-bitfields - +DPERL_MSVC RT_READFIX -s -O2 -DVERSION=\"0.24\" -DXS_VERSION=\"0.24\" + "-IC:\spe rl\perl\lib\CORE" -DINT64_BACKEND_NV Int64.c Int64.c: In function 'SvI64': Int64.c:291: warning: integer constant is too large for 'long' type Int64.c:291: warning: this decimal constant is unsigned only in ISO C9 +0 Int64.c:291: warning: integer constant is too large for 'long' type Int64.c:291: warning: this decimal constant is unsigned only in ISO C9 +0 Int64.c: In function 'SvU64': Int64.c:370: warning: integer constant is too large for 'long' type Int64.c:370: warning: integer constant is too large for 'long' type Running Mkbootstrap for Math::Int64 () C:\sperl\perl\bin\perl.exe -MExtUtils::Command -e "chmod" -- 644 Int64 +.bs dlltool --def Int64.def --output-exp dll.exp g++ -o blib\arch\auto\Math\Int64\Int64.dll -Wl,--base-file -Wl,dll.bas +e -mdll -s -L"C:\sperl\perl\lib\CORE" -L"C:\sperl\c\lib" Int64.o -Wl,--image-bas +e,0x7d4000 00 C:\sperl\perl\lib\CORE\libperl512.a -lmoldname -lkernel32 -luser32 + -lgdi32 - lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi3 +2 -luuid - lws2_32 -lmpr -lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32 dll.exp dlltool --def Int64.def --base-file dll.base --output-exp dll.exp g++ -o blib\arch\auto\Math\Int64\Int64.dll -mdll -s -L"C:\sperl\perl\l +ib\CORE" - L"C:\sperl\c\lib" Int64.o -Wl,--image-base,0x7d400000 C:\sperl\perl\l +ib\CORE\li bperl512.a -lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg3 +2 -ladvapi 32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lwin +mm -lversi on -lodbc32 -lodbccp32 -lcomctl32 dll.exp C:\sperl\perl\bin\perl.exe -MExtUtils::Command -e "chmod" -- 755 blib\ +arch\auto\ Math\Int64\Int64.dll C:\sperl\perl\bin\perl.exe -MExtUtils::Command -e "cp" -- Int64.bs bli +b\arch\aut o\Math\Int64\Int64.bs C:\sperl\perl\bin\perl.exe -MExtUtils::Command -e "chmod" -- 644 blib\ +arch\auto\ Math\Int64\Int64.bs Files found in blib\arch: installing files in blib\lib into architectu +re depende nt library tree Installing C:\sperl\perl\site\lib\auto\Math\Int64\Int64.dll Installing C:\sperl\perl\site\lib\auto\Math\Int64\Int64.exp Installing C:\sperl\perl\site\lib\auto\Math\Int64\Int64.ilk Installing C:\sperl\perl\site\lib\auto\Math\Int64\Int64.lib Installing C:\sperl\perl\site\lib\auto\Math\Int64\Int64.pdb Installing C:\sperl\perl\site\lib\Math\Int64.pm Appending installation info to C:\sperl\perl\lib/perllocal.pod C:\sperl\perl\bin\perl.exe "-MExtUtils::Command::MM" "-e" "test_harnes +s(0, 'blib \lib', 'blib\arch')" t/*.t t/as_int64.t ............ ok t/die_on_overflow.t ..... ok t/Math-Int64-Native.t ... ok t/Math-Int64.t .......... ok t/Math-UInt64-Native.t .. ok t/Math-UInt64.t ......... ok t/MSC.t ................. ok t/pods.t ................ skipped: Only the author needs to check that + POD docs are right All tests successful. Files=8, Tests=256, 2 wallclock secs ( 0.16 usr + 0.08 sys = 0.23 C +PU) Result: PASS C:\Documents and Settings\Owner\Desktop\cpan libs\salva-p5-Math-Int64- +09023f2>
    Also I looked up how GCC does the double to unsigned int64,
    call *__imp__DebugBreak@0 flds LC114 fldl -88(%ebp) fucom %st(1) fnstsw %ax sahf jb L193 fnstcw -26(%ebp) fsubp %st, %st(1) movzwl -26(%ebp), %eax movb $12, %ah movw %ax, -28(%ebp) fldcw -28(%ebp) fistpq -40(%ebp) fldcw -26(%ebp) movl -36(%ebp), %edx movl -40(%ebp), %eax leal -2147483648(%edx), %ecx movl %ecx, %edx jmp L146
    This is from SvU64 from " if (may_die_on_overflow && ( (nv < 0) || (nv >= NV_0x1p64)) ) overflow(aTHX_ out_of_bounds_error_u); return NV2U64(nv);" area. The DebugBreak is right before the return statement and after the overflow check.
      I guess we are done then unless you can think of more tests or something you want to try

      Something is yet failing at the ActiveState build server and there is also some problem with the logs so I am not able to see what is going wrong.

      I have reported the problem but don't know how long it would take to be solved (if it is solved at all!).

        I just saw that is failed on ActiveState :-( The log file will eventually show up I think. I'll be watching until it appears and we will deal with it then I guess.