Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

bignum usage?

by rkd257 (Initiate)
on Oct 15, 2023 at 03:44 UTC ( [id://11154952]=perlquestion: print w/replies, xml ) Need Help??

rkd257 has asked for the wisdom of the Perl Monks concerning the following question:

I must be using bignum incorrectly, as I would have thought I would end up with 5 and 7 on the bottom 2 lines.

0.5833333333333333333333333333333333333333
5833333333333333333333333333333333333333
10000000000000000000000000000000000000000

use Math::BigRat; use bignum; my $cf = 1 - 1/6 - 1/4; ## $cf = 7/12 + \ + my $n = $cf->numerator(); my $d = $cf->denominator(); print "$cf\n"; print " $n\n"; print " $d\n";

Replies are listed 'Best First'.
Re: bignum usage?
by kcott (Archbishop) on Oct 15, 2023 at 05:04 UTC

    G'day rkd257,

    Welcome to the Monastery.

    "... thought I would end up with 5 and 7 ... ## $cf = 7/12 ..."

    So, I think you should have been expecting 7 and 12. If not, please explain why 5 and 7?

    Anyway, I think you want bigrat; not Math::BigRat and bignum. (All three are core modules.)

    $ perl -e ' use bigrat; my $cf = 1 - 1/6 - 1/4; my $n = $cf->numerator(); my $d = $cf->denominator(); print "$cf\n"; print " $n\n"; print " $d\n"; ' 7/12 7 12

    — Ken

Re: bignum usage?
by ikegami (Patriarch) on Oct 17, 2023 at 19:21 UTC

    Replace

    use Math::BigRat; # Useless use bignum; # Uses M::BigInt and M::BitFloat

    with

    use bignum upgrade => "Math::BigRat";
    or
    use bigrat;

    I don't think they're equivalent -- the former initially creates M::BigInt objects and switches to M::BigRat when necessary, but I think the latter uses M::BitRat objects from the start -- but they have the same result here.

Re: bignum usage?
by Anonymous Monk on Nov 23, 2023 at 21:18 UTC

    I wanted to create "bignum usability" SOPW question, but then the SS landed me right here, -- very fresh thread. This pragma is in the core, but how usable/advised/maintained it is?

    use strict; use warnings; use feature 'say'; use bignum; # (1) #use bignum downgrade => "Math::BigInt", upgrade => "Math::BigI +nt"; ## (2) #use bigint; say $^V; say my $x = 21778071482940061661655974875633165533182; say my $y = $x / 2;

    ...

    v5.38.0 21778071482940061661655974875633165533182 10889035741470030830827987437816582766590

    off-by-one error. Using commented-out lines instead gives me (1):

    Deep recursion on subroutine "Math::BigInt::bdiv" at C:/berrybrew/stra +wberry-perl-5.38.0.1-64bit-PDL/perl/site/lib/Math/BigInt.pm line 2229

    and the Perl process hangs, or (2):

    21778071482940061661655974875633165533182 10889035741470030830827987437816582766591

    i.e. "don't use bignum if bigint suffices" will produce the correct answer, but doesn't smell quite right

      off-by-one error

      It seems you've hit some precision limit - which is avoided if you use bigint.
      Try placing an extra number at the beginning of $x, and you'll soon see what I mean.
      For every extra number you prepend to the start of $x, you get an extra "0" at the end of $y:
      use strict; use warnings; use feature 'say'; use bignum;#num; # (1) #use bignum downgrade => "Math::BigInt", upgrade => "Math::BigI +nt"; ## (2) #use bigint; say $^V; my $x = 999999999921778071482940061661655974875633165533182; say $x; my $y = $x / 2; say $y; __END__ For me, outputs: D:\pscrpt>perl try.pl v5.39.5 999999999921778071482940061661655974875633165533182 499999999960889035741470030830827987437800000000000
      Cheers,
      Rob

        Thanks, looks like it's fallback (so called "div_scale", defaults to 40) value that was applied (and now I have a deja-vu to have already investigated this a few years back). Either of

        use bignum p => 0; bignum-> precision( 0 ); bignum-> div_scale( 999 );

        (or method calls on an instance) will help. That still doesn't feel right:

        use strict; use warnings; use feature 'say'; use Data::Dump; use bignum; #use bigint; say my $x = 999999999921778071482940061661655974875633165533182; dd $x; dd $x-> precision; dd $x-> accuracy; dd $x-> div_scale; dd (Math::BigInt-> precision); dd (Math::BigInt-> accuracy); say my $y = $x / 1; __END__ 999999999921778071482940061661655974875633165533182 bless({ sign => "+", value => bless([165533182, 974875633, 61661655, 71482940, 999921778, + 999999], "Math::BigInt::Calc"), }, "Math::BigInt") undef undef 40 undef undef 999999999921778071482940061661655974875600000000000

        But with bigint instead:

        999999999921778071482940061661655974875633165533182 bless({ sign => "+", value => bless([165533182, 974875633, 61661655, 71482940, 999921778, + 999999], "Math::BigInt::Calc"), }, "Math::BigInt") undef undef 40 undef undef 999999999921778071482940061661655974875633165533182

        i.e. object of the same class, with the same properties, same global parameters, but result is different. Same (per deja-vu) conclusion: avoid using bignum.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11154952]
Approved by kcott
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (3)
As of 2024-04-24 05:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found