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

How does Perl conclude the results inf and NaN in the Bash session below? (The execution environment and Perl version are as displayed.)

[[Bash command line prompt]] uname -s -r -v -m -o CYGWIN_NT-6.1-WOW64 1.7.14(0.260/5/3) 2012-04-25 09:41 i686 Cygwin [[Bash command line prompt]] perl -v | grep 'This is perl' This is perl, v5.10.1 (*) built for i686-cygwin-thread-multi-64int [[Bash command line prompt]] cat calc.pl #!/usr/bin/perl -w use strict; use Math::BigFloat ':constant'; print "150 / 0.75 == ", 150 / 0.75, "\n"; print "(int(150.5)) / 0.75 == ", (int(150.5)) / 0.75, "\n"; print "150 / 3.75 == ", 150 / 3.75, "\n"; print "(int(150.5)) / 3.75 == ", (int(150.5)) / 3.75, "\n"; [[Bash command line prompt]] ./calc.pl 150 / 0.75 == 200 (int(150.5)) / 0.75 == inf 150 / 3.75 == 40 (int(150.5)) / 3.75 == NaN

Replies are listed 'Best First'.
Re: Unexpected inf and NaN (+ example)
by LanX (Saint) on Jan 10, 2014 at 09:15 UTC
    I'm too lazy too check¹ it, but it seems obvious that you shouldn't use int (which operates on native types¹) with Math::BigFloat objects.

    from the docs:

    CAVEATS Do not try to be clever to insert some operations in between switching + libraries: ... This will create objects with numbers stored in two different backend +libraries, and VERY BAD THINGS will happen when you use these togethe +r:

    so maybe better use ->bfloor() instead of int !?! :)

    update

    ¹) but curiosity killed my cat: ;-)

    code

    #!/usr/bin/perl -w use strict; use Math::BigFloat ':constant'; use Data::Dump qw/pp/; print "150 / 0.75 == ", 150 / 0.75, "\n"; print "150.5->bfloor() == ", 150.5->bfloor() / 0.75, "\n"; print "150 / 3.75 == ", 150 / 3.75, "\n"; print "150.5->bfloor() / 3.75 == ", 150.5->bfloor() / 3.75, "\n"; my $float=3.1415926; pp $float; pp $float->bfloor(); pp int($float);
    output
    150 / 0.75 == 200 150.5->bfloor() == 200 150 / 3.75 == 40 150.5->bfloor() / 3.75 == 40 bless({ _e => [7], _es => "-", _m => [1415926, 3], sign => "+" }, "Mat +h::BigFloat") bless({ _e => [0], _es => "+", _m => [3], sign => "+" }, "Math::BigFlo +at") bless({ sign => "+", value => [3] }, "Math::BigInt")

    Please note that int produces an object of type Math::BigInt which was never used !!!

    Not sure if Math::BigFloat should better try to overwrite CORE::int() differently...

    Cheers Rolf

    ( addicted to the Perl Programming Language)

    footnote

    ¹) nope it's overwritten, see update and following discussion.

      you shouldn't use int

      Math::BigFloat overloads int(), so it's ok to use it.
      However, the overloaded int() function returns a Math::BigInt object. (I don't see any need for it to do that ... it just makes things confusing.)

      Anyway, *that*, of course, brings us to the caveat you mentioned.

      Cheers,
      Rob
        > However, the overloaded int() function returns a Math::BigInt object.

        agreed, see my update in the meantime.

        > (I don't see any need for it to do that ... it just makes things confusing.)

        Math::BigInt is mentioned quite often in the docs, e.g.

        Math library Math with the numbers is done (by default) by a module called Math::Bi +gInt::Calc. This is equivalent to saying:

        So I suppose there is some intended interoperability between these modules.

        Obviously a good reason for a bug report, though my impression is that the whole thing will need a redesigned.

        edit

        Or maybe good case of tl;dr... there is really much stuff to read and I'm still mid-coffee ... ;-)

        Cheers Rolf

        ( addicted to the Perl Programming Language)

      bignum

      use bignum; print "150 / 0.75 == ", 150 / 0.75, "\n"; print "(int(150.5)) / 0.75 == ", (int(150.5)) / 0.75, "\n"; print "150 / 3.75 == ", 150 / 3.75, "\n"; print "(int(150.5)) / 3.75 == ", (int(150.5)) / 3.75, "\n"; __END__ 150 / 0.75 == 200 (int(150.5)) / 0.75 == 200 150 / 3.75 == 40 (int(150.5)) / 3.75 == 40

      and

      use Data::Dump qw/ dd /; use bignum; dd( (int(150.5)) / 3.75 ) __END___ bless({ _e => [1], _es => "+", _m => [4], sign => "+" }, "Math::BigFlo +at")