Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

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.

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
        chop off exponent (11 bits)
        == 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/ in perl.git.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://974260]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (5)
As of 2018-06-18 04:34 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (107 votes). Check out past polls.