Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Re: Dividing and format

by tadman (Prior)
on Nov 27, 2003 at 16:38 UTC ( [id://310559]=note: print w/replies, xml ) Need Help??


in reply to Dividing and format

You can do it with straight math, too:
sub round_to { my ($value, $places) = @_; my $exp = 10 ** $places; return int(($value * $exp * 10 + 5) / 10) / $exp; } print round_to(12678/1000, 1),$/;

Replies are listed 'Best First'.
Re: Re: Dividing and format
by TheFluffyOne (Beadle) on Nov 27, 2003 at 17:41 UTC

    Perhaps bizarrely, tadman's code doesn't work with all numbers. I think it's internal rounding errors on Perl's part rather than a fault with the code (though I could be wrong :). I've broken down the code to analyse what's going on, viz:

    $number = 12650 / 10000; $dp = 2; print "Actual: $number\n"; my $exp = 10 ** $dp; $val1 = $number * $exp; $val2 = $val1 + 0.5; $val3 = int($val2); $val4 = $val3 / $exp; print "val1 = value x exp = $val1\n"; print "val2 = val1 + 0.5 = $val2\n"; print "val3 = int(val2) = $val3\n"; print "val4 = val3 / exp = $val4\n";

    The output:

    Actual: 1.265 val1 = value x exp = 126.5 val2 = val1 + 0.5 = 127 val3 = int(val2) = 126 val4 = val3 / exp = 1.26

    Verified on Win32 with ActivePerl 5.8.1 b807, and in Linux with Perl 5.8.0.

    Replace the first line with "$number = 1.265;", however, and you get the correct result. Weird.

      It's probably storing "127" as 126.9999999999999 which rounds down with the int function. Aren't floating point numbers fun?

      The documentation for int suggests that the POSIX::floor function is a better selection for this kind of work.

      Ok Goron I brought the int function up sooner to get rid of the floating point asp. And to remove decimels from the addition portion. Seen in this code based of yours.

      Code

      use strict; my $number = 12650 / 10000; #my $number = 1.265; my $dp = 2; print "Actual: $number\n"; my $exp = 10 ** ($dp+1); my $val1 = int($number * $exp); my $val2 = $val1 + 5; my $val4 = $val2 / $exp; print "val1 = value x exp = $val1\n"; print "val2 = val1 + 5 = $val2\n"; #print "val3 = int(val2) = $val3\n"; print "val4 = val2 / exp = $val4\n";

      Output

      Actual: 1.265 val1 = value x exp = 1265 val2 = val1 + 5 = 1270 val4 = va2 / exp = 1.27

      Ok I messed it up if you use 1200 you get 12.05 so I think you need to do it in steps throwing away un needed decimals. Oh well need to catch a train will play with it tonight because it is not Internet Explorer and I need something that is not Internet Explorer.

      "No matter where you go, there you are." BB

        The reason this doesn't work is that you're doing the "+5" after the int statement. The purpose of the +5 (or +0.5) is to ensure that the int rounds down anything below x.5 and rounds up anything x.5 and above.

        It's so that:

        int(0.4 + 0.5) = int(0.9) and therefore 0.4 rounds down to 0.

        int(0.5 + 0.5) = int(1.0) and therefore 0.5 rounds up to 1.

        How I long for the good old days of MC68000 programming, where there was no such thing as floating point :)

Re: Re: Dividing and format
by davido (Cardinal) on Nov 27, 2003 at 17:20 UTC
    hotshot mentioned that he wanted 12000/1000 to print as "12.0". Your pure-math method results in output of "12", and thus doesn't meet the OP's specifications.

    It would seem that, given he wishes not to use printf or formats, his best bet is the sprintf tool.


    Dave


    "If I had my life to live over again, I'd be a plumber." -- Albert Einstein
      Eventually you're going to have to use something printf-like function such as sprintf anyway. I was just proposing something that kept the numbers as numbers instead of stringifying them. It is numerically 12.0, even if print decides to show it as 12 without the decimal.

      That being said, any time you're dealing with floating point numbers it's pretty much advised to use some kind of formatting method. Some numbers might be assigned a value of 12.0 but end up displaying as 11.9999999999999999981 instead, or even 12.00000000000000012.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://310559]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (4)
As of 2024-04-25 07:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found