http://qs321.pair.com?node_id=724170

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

Simple question. I need a simple way of detecting values that are "sub penny".. Is there a better way to do it than this? (I believe the code is correct, but I'm hoping there may be a faster implementation)
sub is_subpenny { my $number = $_[0]; return (($number*100) - int($number*100) > 0); }

Replies are listed 'Best First'.
Re: modulus and floating point numbers
by GrandFather (Saint) on Nov 18, 2008 at 02:34 UTC
    sub is_subpenny { my $number = abs ($_[0] * 100); return $number - int ($number) > 0; }

    is faster by avoiding an extra multiply and also works for negative numbers although the abs may slow it down again.


    Perl reduces RSI - it saves typing
Re: modulus and floating point numbers
by BrowserUk (Patriarch) on Nov 18, 2008 at 02:57 UTC
      how about .00001 ?

        I'm not sure if I understand the question, but:

        [0] Perl> print fmod( $_, 100 ) for 12300, 12301, 12399, .00001;; 0 1 99 1e-005

        Or do you mean this:

        [0] Perl> print fmod( $_, 1 ) for map{ ($_, -$_ ) } 12300, 12301, 1239 +9, .00001;; 0 0 0 0 0 0 1e-005 -1e-005

        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: modulus and floating point numbers
by ccn (Vicar) on Nov 18, 2008 at 03:17 UTC
    #!/usr/bin/perl use strict; use warnings; use Benchmark qw(cmpthese); my @a = map { (rand() * 1000) / 1000 } 1 .. 1000; cmpthese(-1, { 'GF' => sub {GF($_) for @a}, 'GF2' => sub {GF2($_) for @a}, 'dex' => sub {dex($_) for @a}, 'ccn' => sub {ccn($_) for @a}}); sub GF { my $number = abs($_[0] * 100); return $number - int ($number) > 0; } sub GF2 { my $number = $_[0] * 100; return $number - int ($number) > 0; } sub ccn { $_[0] =~ /\..../; } sub dex { my $number = $_[0]; return (($number*100) - int($number*100) > 0); } __END__ Rate dex GF GF2 ccn dex 931/s -- -7% -19% -28% GF 1000/s 7% -- -13% -23% GF2 1152/s 24% 15% -- -11% ccn 1297/s 39% 30% 13% --
      You took off the addition and the parens.. I got..
      Rate ccn dex GF GF2 ccn 296/s -- -73% -74% -76% dex 1097/s 270% -- -2% -10% GF 1124/s 279% 2% -- -7% GF2 1213/s 309% 11% 8% --
        I took off addition wittingly. One can skip addition if input data is numeric. Situation becomes worse if input must be validated.

        And once again, I am not shure if we can rely on the third digit after a floating point. Indeed, I will never use that sub.

Re: modulus and floating point numbers
by ccn (Vicar) on Nov 18, 2008 at 02:45 UTC
    I am not sure, but what about?
    sub is_subpenny { ($_[0]+0) =~ /\..../; }