in reply to Re: How to determine whether a number has a decimal component?
in thread How to determine whether a number has a decimal component?

Wow, that's the first time i've seen Perl do something truly dumb.

Anyhow, the origin shouldn't matter. I'm looking for methods that work in all circumstances on the very simple question of "Is this an int or a float?" As such the comparison thing doesn't matter much either, since i doubt it'll store pre-decimal components in a manner that would make them come out as a decimal when retrieved from ram.

Edit: So why do people vote this down? Can't handle it when people speak their mind about Perl? Did i say something really stupid without realizing? I'm not trolling here, so at least let me know if and when I'm wrong.
  • Comment on Re^2: How to determine whether a number has a decimal component?

Replies are listed 'Best First'.
Re^3: How to determine whether a number has a decimal component?
by gone2015 (Deacon) on Jan 04, 2009 at 21:03 UTC

    The problem with floating point (and binary floating point and decimal fractions) is not strictly Perl's fault.

    Any calculation in floating point can end up accumulating rounding errors. This will happen in any language.

    Conversion of a decimal fraction to binary floating point introduces a small "representation error" most of the time, because most decimal fractions turn out to be recurring binary ones. Conversion from binary to decimal, for example in print tends to round to some number of decimal digits, so "representation error" is usually hidden. This rounding on output can also mask some rounding errors. Any system that uses binary floaing point will suffer from this issue -- and most do !

    If all you want to know is whether the value you have in your hands has a non-zero fractional part, then $x - int($x) will tell you. But, depending on how the value $x was arrived at, be prepared for this to tell you there is a fraction, despite print $x showing none... for example:

    my $x = (1 - 0.99) * 100 ; print $x, ($x - int($x)) ? " has fraction" : " no fraction", "\n" ;
    ...answering your later question, you may get false positives -- things which don't look as if they have fraction bits may be reported as having some.

    Incidentally int($x) in Perl does not force its result into an integer form. If $x is a very large floating value, so large that there cannot be any fraction bits, it will simply return the original value of $x. If $x is a large floating value, with one or more fraction bits, but an integer part too big for integer form, it will discard the fraction bits but still return a floating point value. You are in no danger of things going wrong (as they would do if int tried to return, say, a 32-bit integer).

      Just want to note that example may be fixed as follows:

      my $x = (1 - 0.99) * 100 ; print $x, ("$x" - int($x)) ? " has fraction" : " no fraction", "\n" ;
      Thanks for the more detailed explanation, i didn't know about the print rounding. As for getting false positives, not a problem at all for my case. :)
Re^3: How to determine whether a number has a decimal component?
by GrandFather (Saint) on Jan 04, 2009 at 21:23 UTC

    If by "something truly dumb" you mean "equalness might fail due to rounding issues"

    that ain't Perl, it's a function of performing "real" arithmetic using finite precision and is unavoidable (most numbers can't be represented using finite precision).

    Why the down votes? I don't know, but it may be people are assuming you didn't read Why do floating point numeric equality/inequality tests fail mysteriously? and the material linked from that node and said something "truly dumb" in consequence. ;)


    Perl's payment curve coincides with its learning curve.
    A reply falls below the community's threshold of quality. You may see it by logging in.