Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Floating point calculus error...
- X-seq: zsh-users 5289
- From: "Bart Schaefer" <schaefer@xxxxxxxxxxxxxxxx>
- To: Patrick Aussems <zyk@xxxxxxxxxxxxxx>, zsh-users@xxxxxxxxxx
- Subject: Re: Floating point calculus error...
- Date: Sun, 25 Aug 2002 16:37:06 +0000
- In-reply-to: <1030288941.517.8.camel@Amok>
- Mailing-list: contact zsh-users-help@xxxxxxxxxx; run by ezmlm
- References: <1030288941.517.8.camel@Amok>
On Aug 25, 5:22pm, Patrick Aussems wrote:
}
} I was doing some shell scripts that were supposed to add CPU usages from
} the ps output... But I got puzzled when I got an answer with a 17th
} decimal while adding numbers with only 1 decimal... Strange isn't it?
Not really.
schaefer[507] print -l $[0.1] $[0.2] $[0.3] $[0.4]
0.10000000000000001
0.20000000000000001
0.29999999999999999
0.40000000000000002
schaefer[508] typeset -F 4 f
schaefer[509] for f in $[0.1] $[0.2] $[0.3] $[0.4]; print $f
0.1000
0.2000
0.3000
0.4000
} The value returned is: 0.80000000000000004 which is obviously not the
} correct answer... Okay, floating points numbers are inaccurate, but
} still...
Yes, floating point numbers are inaccurate. Zsh simply doesn't round
when inside arithmetic expressions, only when outputting float-formatted
parameters where it knows how many decimal places to use (default 10, but
I forced 4 above).
For comparison, see what happens when the number is computed by floating
point addition rather than by explicit conversion from decimal. In the
first example below (history number [510]) I've used $(($f)) to force zsh
to round down to 1 decimal place and then convert back to float again.
In the second case, $((f)) evaluates f entirely in math context, using as
much precision as possible, which also shows why the first case didn't stop
at 0.9.
schaefer[510] typeset -F 1 f ; for ((f=0; f < 1; f += 0.1)) print $f = $(($f))
0.0 = 0
0.1 = 0.10000000000000001
0.2 = 0.20000000000000001
0.3 = 0.29999999999999999
0.4 = 0.40000000000000002
0.5 = 0.5
0.6 = 0.59999999999999998
0.7 = 0.69999999999999996
0.8 = 0.80000000000000004
0.9 = 0.90000000000000002
1.0 = 1
schaefer[511] typeset -F 1 f ; for ((f=0; f < 1; f += 0.1)) print $f = $((f))
0.0 = 0
0.1 = 0.10000000000000001
0.2 = 0.20000000000000001
0.3 = 0.30000000000000004
0.4 = 0.40000000000000002
0.5 = 0.5
0.6 = 0.59999999999999998
0.7 = 0.69999999999999996
0.8 = 0.79999999999999993
0.9 = 0.89999999999999991
1.0 = 0.99999999999999989
--
Bart Schaefer Brass Lantern Enterprises
http://www.well.com/user/barts http://www.brasslantern.com
Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net
Messages sorted by:
Reverse Date,
Date,
Thread,
Author