What is the origin of $number?

If it is read from a textual representation (STDIN, File), personally I would chose method 1. to scan for a dot followed by digits where at least one digit is not zero (something along $number =~ /\.0*[1-9]\d*/). Scanning for a dot allone is not sufficient.

If the origin of $number is a computation, than you have to take care of rounding issues when you apply method 2. Comparing $number with int($number) for equalness might fail due to rounding issues. So it might be more robust to do a comparison along abs($number - int($number)) < $epsilon (see Why do floating point numeric equality/inequality tests fail mysteriously?).

Update: Please note GrandFather's correct comment about the special case of the comparison $number == int($number). Indeed, abs($number - int($number)) itself may lead to false positives when $epsilon is ill chosen (see below).

E.g., on my computer, the following snipped produces a nice table of the floating point representation of various 'integers' together with some interesting floats:
for my $a (-2..10, 0.2, -0.2, 1 + 0.25e-15) { $_ = unpack("b*", pack("d", $a)); # double to bit-pattern s/(.{8})/$1 /g; tr[0][.]; # grouping&fmt. $_ = reverse $_; # formatting s/^(..)(.{12})(.*)/Sgn:$1 Exp: $2 Mant:(1,)$3/; print "$a\t -- $_\n"; }

-2   -- Sgn: 1  Exp: 1...... ....  Mant: (1,).... ........ ........ ........ ........ ........ ........
-1 -- Sgn: 1 Exp: .111111 1111 Mant: (1,).... ........ ........ ........ ........ ........ ........
0 -- Sgn: . Exp: ....... .... Mant: (1,).... ........ ........ ........ ........ ........ ........
1 -- Sgn: . Exp: .111111 1111 Mant: (1,).... ........ ........ ........ ........ ........ ........
2 -- Sgn: . Exp: 1...... .... Mant: (1,).... ........ ........ ........ ........ ........ ........
3 -- Sgn: . Exp: 1...... .... Mant: (1,)1... ........ ........ ........ ........ ........ ........
4 -- Sgn: . Exp: 1...... ...1 Mant: (1,).... ........ ........ ........ ........ ........ ........
5 -- Sgn: . Exp: 1...... ...1 Mant: (1,).1.. ........ ........ ........ ........ ........ ........
6 -- Sgn: . Exp: 1...... ...1 Mant: (1,)1... ........ ........ ........ ........ ........ ........
7 -- Sgn: . Exp: 1...... ...1 Mant: (1,)11.. ........ ........ ........ ........ ........ ........
8 -- Sgn: . Exp: 1...... ..1. Mant: (1,).... ........ ........ ........ ........ ........ ........
9 -- Sgn: . Exp: 1...... ..1. Mant: (1,)..1. ........ ........ ........ ........ ........ ........
10 -- Sgn: . Exp: 1...... ..1. Mant: (1,).1.. ........ ........ ........ ........ ........ ........
0.2 -- Sgn: . Exp: .111111 11.. Mant: (1,)1..1 1..11..1 1..11..1 1..11..1 1..11..1 1..11..1 1..11.1.
-0.2 -- Sgn: 1 Exp: .111111 11.. Mant: (1,)1..1 1..11..1 1..11..1 1..11..1 1..11..1 1..11..1 1..11.1.
1 -- Sgn: . Exp: .111111 1111 Mant: (1,).... ........ ........ ........ ........ ........ .......1
See the last line representing the smalles double greater than 1.0 ((1,)0000....00001)? (Not only) here, the given $epsilon-test would lead to a false positive if $epsilon was chosen too "big". In case int() is properly implemented (a valid assumption for modern CPUs and implementations, see IEEE_754), the integer part can be extracted without loss of precision from the float representation by shifting and masking the mantissa. For a real integer, this operation will lead to identical bit patterns that can be compared for equality.
my $a = 1+0.25e-15;# hidden bit and last bit of mantissa: 1 print "Test : is int.? correct?\n"; print "a != int(a) : no yes\n" if $a != int($a); $d = abs($a - int($a)); print "abs(a-int(a) < 1e-15: yes no!\n" if $d<1e-15; print "abs(a-int(a) < 1e-40: yes ???\n" if $d<1e-40; print "abs(a-int(a) > 0 : no yes\n" if $d>0; printf("epsilon < %g required (here!)\n", $d); __END__ Test : is int.? correct? a != int(a) : no yes abs(a-int(a) < 1e-15: yes no! abs(a-int(a) > 0 : no yes epsilon < 2.22045e-16 required (here!)
OK, the comparison of $a and int($a) yields the correct result ($a is not an integer). But choosing the wrong $epsilon (e.g., here: 1e-15) would lead to a false positive - a typical characterstic when comparing against a limit - the limit controls the distribution of errors of first and second kind.
In the light of the OPs, question, it is better to directly compare $number with int($number) than doing the $epsilon-trick. Though, when comparing to different floats ($number1 and $number2), comparing the delta against a tolerance is advisable. Here is a nice article about Comparing Floating Point Numbers.


In reply to Re: How to determine whether a number has a decimal component? by Perlbotics
in thread How to determine whether a number has a decimal component? by Xenofur

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.