Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Re: Filthy Floats

by bikeNomad (Priest)
on Jul 16, 2001 at 20:13 UTC ( [id://97068]=note: print w/replies, xml ) Need Help??


in reply to Filthy Floats

Use sprintf to set the number of significant digits you want:

# rounds to 0.01 (assumes positive number): my $cleanFloat = sprintf "%.2f", $dirtyFloat + 0.004; # truncates to 0.01: my $cleanFloat = sprintf "%.2f", $dirtyFloat;

update: it appears that sprintf internally rounds, which makes my "truncates" example not do so. However, the "rounds" example may be better, as it gets around sprintf's buggy rounding.

update2: but since sprintf does buggy rounding for 0.5, it would be better to add 0.004; changed this.

Replies are listed 'Best First'.
Re: Re: Filthy Floats
by Hofmator (Curate) on Jul 16, 2001 at 20:53 UTC

    Watchout, (s)printf does the rounding itself, it doesn't truncate!

    printf "%.3f => %.2f\n", 1.023, 1.023; printf "%.3f => %.2f\n", 1.026, 1.026; #prints 1.023 => 1.02 1.026 => 1.03
    but sadly this rounding is buggy on numbers ending in .5:
    printf "%.5f => %.2f\n", 1.025, 1.025; # prints instead of the correct 1.03 1.025 => 1.02
    A quick and ugly 'fix' is something like printf "%.5f => %.2f\n", 1.025+1e-10, 1.025+1e-10; For better solutions and some discussion see this recent thread.

    -- Hofmator

      Hmm... not so sure that is buggy. I think a fairly common usage of round is for numbers that end in with 5 in the last place is to round to the even number. Wierd but true.

      No I don't have a reference, so that is just my recollection.

      Scott

      Actually, round to even would be correct for numbers ending in .5
      But in this case, 1.025 really is closer to 1.02
      printf "%.20f => %.2f\n", 1.025, 1.025;

        Actually, round to even would be correct for numbers ending in .5

        This is new to me, up to now I always rounded .5 up. But you seem to be right, e.g. Mathematica rounds in that way. The reason for this is that the rounding should not give a statistical bias - as far as I understand it.

        But in this case, 1.025 really is closer to 1.02 printf "%.20f => %.2f\n", 1.025, 1.025;
        # this prints 1.02499999999999990000 => 1.02
        D'oh, well, been tripped up again by floating point number representations (tye explains that very nicely here in this thread) ...

        What is interesting is the following example where the rounding towards the nearest even number (0) does not take place - and the 0.5 can be represented exactly as a float (as merlyn pointed out somewhere else in this node):

        printf "%.20f => %.0f", 0.5, 0.5; # prints 0.50000000000000000000 => 1

        -- Hofmator

Re: Re: Filthy Floats
by abstracts (Hermit) on Jul 16, 2001 at 21:12 UTC
    Hello, The function sprintf does the rounding automatically. You don't need to add the 0.005.

    From the sprintf manual:

    f,F  The  double  argument  is  rounded and 
    converted to decimal notation in the style -ddd.ddd, 
    where the number  of digits after the decimal-point 
    character is equal to the precision  specification.  
    
    Doing a small test reveals the same behavior in perl:
    #!/usr/bin/perl -w
    print `cat $0`;
    for $i (1..10){
    	my $num = 0;
    	for(1..9800*$i){
    		$num += 0.0001/$i;
    	}
    	print "$num = ";
    	$num = sprintf("%.4f", $num);
    	print "$num\n";
    }
    0.979999999999908 = 0.9800
    0.9799999999999 = 0.9800
    0.979999999999902 = 0.9800
    0.980000000000962 = 0.9800
    0.980000000000699 = 0.9800
    0.979999999999897 = 0.9800
    0.980000000000605 = 0.9800
    0.979999999999383 = 0.9800
    0.979999999998648 = 0.9800
    0.979999999998175 = 0.9800
    
    Aziz,,,

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (3)
As of 2024-04-26 04:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found