No, truncation is correct in this case. ... as the rounding error seen in my original post was introduced by storing the string representation into a binary float

Whatever works for you.

I am just saying that not all price strings translate into a double that is bigger than the string value, and you will want to make sure that your application doesn't have any situations like the following, for the string "1.13", which has a binary representation slightly less than 1.13 for both double precision and single precision:

C:\usr\local\share\PassThru\perl>perl -le "print int(100*'1.13')" 112 C:\usr\local\share\PassThru\perl>perl -MPOSIX=round -le "print round(1 +00*'1.13')" 113

If your application doesn't have that problem, then great.

However, I still don't see why my suggestion won't work for you. It would be nice for you to show me one example of a price-string to put in $from_api that will not become the right integer number of cents when run through my second section of code:

#### redo, with proper rounding $from_api = get_from_api(); print "string from_api = '$from_api' straight from api\n"; $from_api .= '.' unless $from_api =~ /\./; $from_api .= '00'; $from_api =~ s,^(\d+)\.(\d{2})(\d*).*$,${1}${2}.${3},; print "string from_api = '$from_api' after text manipulation\n"; $from_api = round($from_api); print "good rounding = ", $from_api, "cents\n";

Here's a testbed, showing that for reasonable strings, our two match. It also shows a couple strange variants, where there's at least one place where your truncation and my rounding come up with different results.

use warnings; use strict; use POSIX qw/round/; use Test::More; for my $correct_integer_cents ( 0 .. 200 ) { # first, let's create a testbench using the integer number of cent +s as the basis my $price_string = "00" . $correct_integer_cents; $price_string =~ s/(\d{2})$/.$1/; my $price_float = $correct_integer_cents / 100; my $test_name = sprintf "cents=%s str='%s' float='%.15f'", $correc +t_integer_cents, $price_string, $price_float; # Now let's compare how your converter and my converter deal with +these is anotherguest($price_string), $correct_integer_cents, "anothergu +est | $test_name"; is pryrt($price_string), $correct_integer_cents, "pryrt + | $test_name"; } # so both are identical for those 201 tests. # however, what about weird situations for my $price_string ( '1.13', '1.130000000', 1.13 , sprintf('%.18f', +1.13) ) { is anotherguest($price_string), 113, "anotherguest | str='$price_s +tring'"; is pryrt($price_string), 113, "pryrt | str='$price_s +tring'"; } done_testing;

In reply to Re^5: number comparison with a twist by pryrt
in thread number comparison with a twist by anotherguest

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.