Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Re^18: supporting quads on 32 bit Perl

by salva (Abbot)
on Jun 04, 2012 at 10:22 UTC ( #974260=note: print w/ replies, xml ) Need Help??


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

Yes, this is an error in Test::More calling some overload method directly with an incorrect number of arguments.

I have changed Math::Int64 to support it anyway and also solved a problem with MS compiler not being able to handle uint64 to double conversions.

Version 0.22 is now available from CPAN.


Comment on Re^18: supporting quads on 32 bit Perl
Replies are listed 'Best First'.
Re^19: supporting quads on 32 bit Perl
by bulk88 (Priest) on Jun 04, 2012 at 13:57 UTC
    0.22 from CPAN will not compile. All the errors follow the same format.
    Int64.xs(974) : error C2275: 'int64_t' : illegal use of this type as a +n expressi on Int64.xs(22) : see declaration of 'int64_t'
    Given this XS code
    SV *mi64_right(self, other, rev = &PL_sv_no) SV *self SV *other SV *rev CODE: int64_t a; uint64_t b; if (SvTRUE(rev)) { a = SvI64(aTHX_ other); b = SvU64x(self); } else { a = SvI64x(self); b = SvU64(aTHX_ other); }
    which produces this C code
    XS(XS_Math__Int64__right); /* prototype to pass -Wmissing-prototypes * +/ XS(XS_Math__Int64__right) { #ifdef dVAR dVAR; dXSARGS; #else dXSARGS; #endif if (items < 2 || items > 3) croak_xs_usage(cv, "self, other, rev = &PL_sv_no"); { SV * self = ST(0); SV * other = ST(1); SV * rev; SV * RETVAL; if (items < 3) rev = &PL_sv_no; else { rev = ST(2); } #line 974 "Int64.xs" int64_t a; uint64_t b; if (SvTRUE(rev)) { a = SvI64(aTHX_ other); b = SvU64x(self); } else { a = SvI64x(self); b = SvU64(aTHX_ other); }
    The error is obvious. You need to use PREINIT. Never rely on typemap entries being 1 liners and initialization not being deferred by XSPP. You can open new blocks, create new C autos, and run 1/4 page of code from a typemap entry. You can even run perl code to generate the type entry in the XS sub. For example to get accept a reference and its target.
    T_REFANDSV ".(unshift(@line, ( 'PREINIT:', ' SV * '.$var.'Ref;', 'INPUT:')),''). "${\$var}Ref = $arg; if (SvROK(${\$var}Ref)) $var = (SV*)SvRV(${\$var}Ref); else Perl_croak(aTHX_ \"%s: %s is not a reference\", ${$ALIAS?\q[GvNAME(CvGV(cv))]:\qq[\"$pname\"]}, \"$var\");
      0.23 is out.

      This time I have compiled it with gcc -pedantic -std=c89 and removed all the nonstandard constructions...

        I just tried 0.23 from CPAN. Math::Int64 doesn't croak when called by Test::More after a test failed anymore. Compiled without errors. I used it in my module and write a small test suite that uses Math::Int64 without any problems. I did fail a test from Math::Int64 though.
        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 ................. 1/3 # Failed test 'uint64 to NV conversion 3' # at t/MSC.t line 15. # Looks like you failed 1 test of 3. t/MSC.t ................. Dubious, test returned 1 (wstat 256, 0x100) Failed 1/3 subtests t/pods.t ................ skipped: Only the author needs to check that + POD docs are right Test Summary Report ------------------- t/MSC.t (Wstat: 256 Tests: 3 Failed: 1) Failed test: 3 Non-zero exit status: 1 Files=8, Tests=256, 1 wallclock secs ( 0.24 usr + 0.02 sys = 0.25 C +PU) Result: FAIL Failed 1/8 test programs. 1/256 subtests failed. NMAKE : fatal error U1077: 'C:\perl512\bin\perl.exe' : return code '0x +ff' Stop. C:\Documents and Settings\Owner\Desktop\cpan libs\Math-Int64-0.23> C:\Documents and Settings\Owner\Desktop\cpan libs\Math-Int64-0.23>perl + ./t/MSC.t 1..3 ok 1 - uint64 to NV conversion ok 2 - uint64 to NV conversion 2 not ok 3 - uint64 to NV conversion 3 # Failed test 'uint64 to NV conversion 3' # at ./t/MSC.t line 15. # Looks like you failed 1 test of 3. C:\Documents and Settings\Owner\Desktop\cpan libs\Math-Int64-0.23>
        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
        void TwoSVs( one, two ) SV * one SV * two PPCODE: 0;
        called as
        my $u = string_to_uint64('0xff00_0000_0000_0000'); Dump($u); my $nv = uint64_to_number($u); Dump($nv); Local::XS::TwoSVs($u, $nv);
        which showed
        SV = IV(0xb04240) at 0xb04244 REFCNT = 1 FLAGS = (PADMY,ROK) RV = 0x397e8c SV = PVMG(0x8eaf6c) at 0x397e8c REFCNT = 1 FLAGS = (OBJECT,NOK,OVERLOAD,pNOK) IV = 0 NV = -5.48612406879369e+303 PV = 0 STASH = 0x8616cc "Math::UInt64" SV = NV(0x86ab0c) at 0x82bd0c REFCNT = 1 FLAGS = (PADMY,NOK,pNOK) NV = 1.83746864796716e+019
        $u's &($u->sv_u.svu_rv->sv_any->xnv_u) in raw memory is
        0x008EAF6C 00 00 00 00 00 00 00 ff
        $nv's &($nv->sv_any->xnv_u) in raw memory is
        0x0086AB0C 00 00 00 00 00 e0 ef 43
        ok lets try this
        my $u = string_to_uint64('0xff00_0000_0000_0000'); my $nv = uint64_to_number($u); print "nv $nv u $u \n\n";
        result is
        nv 1.83746864796716e+019 u 18374686479671623680
        IDK how many floating point digits are supposed to be shown. VS debugger says the NV slot in the SVNV is "1.8374686479671624e+019".
        (__int64 *)&(two->sv_any->xnv_u)
        == 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
        my $u = string_to_uint64('0xff00_0000_0000_0000'); my $nv = uint64_to_number($u);
        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.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://974260]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (11)
As of 2015-07-30 22:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (273 votes), past polls