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

What other options are there for finding the correct integer? I tried but got an error:
use POSIX; print int(0.6505 / 0.0001); print "\n"; print sprintf("%d", 0.6505 / 0.0001);
-> 6504 need 6505

Replies are listed 'Best First'.
Re: finding the correct integer
by LanX (Cardinal) on Nov 30, 2020 at 14:57 UTC
    That's a classic, computers use a binary representation for floats and many decimal fractions can't be represented w/o rounding errors

    see Humans have too many fingers

    Depending on use case there are different solutions, one is to calculate with integers without decimal fractions (like do currency in cent and add the point only at output)

    PS: we had a similar discussion just recently

    int() function

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

Re: finding the correct integer
by haukex (Bishop) on Nov 30, 2020 at 16:17 UTC
Re: finding the correct integer
by BillKSmith (Prior) on Nov 30, 2020 at 16:10 UTC
    The "%f" format does rounding to the specified precision. In this case use:
    print sprintf("%4.0f\n", 0.6505 / 0.0001);

    OUTPUT:

    6505
    Bill
      Yes, it does in the case the OP provided.

      But it's important to keep in mind that accumulated rounding errors for longer calculations won't be magically compensated.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        LanX and haukex have the "right" answer here. Sure, various things can be done to coax "the right answer" out of "this example," but the underlying mathematical issues are still there and can't be evaded.
      another nitpick, the OP asked for int not rounding

      please compare:

      DB<6> print int 0.65049 / 0.0001; 6504 DB<7> printf("%4.0f\n", 0.65049 / 0.0001); 6505 DB<8>

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

Re: finding the correct integer
by johngg (Canon) on Nov 30, 2020 at 14:57 UTC

    Using int will truncate so if the result, due to the inexact way a computer will represent 0.0001, is, say, 6504.9999997 it will end up as 6504. This seems to work.

    johngg@abouriou:~/perl/Monks$ perl -E 'say 0.6505 / 0.0001;' 6505

    Cheers,

    JohnGG

      your code not return integer
      print 0.65051 / 0.0001; 6505.1

        Your code does not duplicate johngg's code.


        Give a man a fish:  <%-{-{-{-<

Re: finding the correct integer
by perlfan (Vicar) on Nov 30, 2020 at 18:06 UTC
    What precision are you expecting? Math::BigFloat may assist, but it doesn't seem like you're needing that hammer. Documentation on int states, You should not use this function for rounding: one because it truncates towards 0, and two because machine representations of floating-point numbers can sometimes produce counterintuitive results. Furthermore, Usually, the sprintf, printf, or the POSIX::floor and POSIX::ceil functions will serve you better than will int. You're already using POSIX so take a look at ceil or floor, depending on what you're expecting.