Perl subtraction wierdness

J

jai_guevara

I'm finding some simple subtractions that result in negative numbers
give wierd results. I know I could use sprintf to format it, but
shouldn't this just work?
perl -e 'print 17.50-18.30'
-0.800000000000001
perl -e 'print 18.00-18.30'
-0.300000000000001

My perl version is v5.8.6 built for i586-linux-thread-multi.
 
B

Brian Wakem

I'm finding some simple subtractions that result in negative numbers
give wierd results. I know I could use sprintf to format it, but
shouldn't this just work?


My perl version is v5.8.6 built for i586-linux-thread-multi.


perldoc -q numbers
 
D

Dr.Ruud

(e-mail address removed):
I'm finding some simple subtractions that result in negative numbers
give wierd results. I know I could use sprintf to format it, but
shouldn't this just work?

What do you consider weird (or 'wierd' as you spell it) about it?
 
T

Tad McClellan

I'm finding some simple subtractions that result in negative numbers
give wierd results. I know I could use sprintf to format it, but
shouldn't this just work?


That isn't weird, that is a consequence of computers working
on floating-point numbers represented in base 2 (binary).

perldoc -q numbers

Why am I getting long decimals (eg, 19.9499999999999) instead of the
numbers I should be getting (eg, 19.95)?
 
E

Eric J. Roode

(e-mail address removed) wrote in @f14g2000cwb.googlegroups.com:
I'm finding some simple subtractions that result in negative numbers
give wierd results. I know I could use sprintf to format it, but
shouldn't this just work?


My perl version is v5.8.6 built for i586-linux-thread-multi.

I swear, they should teach kids about assembly language, registers, and
data representations. Why, back in my day....
</old-person-rant>

Okay. Duuuude. You think computers have infinite precision? No, that
would require infinite memory. Ah, but I hear you say, "17.50 doesn't
require infinite precision, just two decimal places! Same with 18.30!"
Right. *Decimal places*. Computers do computations in *binary*. The
numbers 17.50 and 18.30 simply *cannot* be represented exactly in the
commonly-used binary floating-point representations used in most modern
computers. Suck it up. (actually, I lied. 17.50 *can* be represented
exactly. But not 18.30).

You cannot expect 17.50 plus 0.80 to equal 18.30. You have to allow for
this. (Yeah, you'd expect a modern proglang like Perl to account for
this, but it doesn't. Oh well.)

Read the FAQ; also read up on data representation of floating-point
numbers.

--
Eric
`$=`;$_=\%!;($_)=/(.)/;$==++$|;($.,$/,$,,$\,$",$;,$^,$#,$~,$*,$:,@%)=(
$!=~/(.)(.).(.)(.)(.)(.)..(.)(.)(.)..(.)......(.)/,$"),$=++;$.++;$.++;
$_++;$_++;($_,$\,$,)=($~.$"."$;$/$%[$?]$_$\$,$:$%[$?]",$"&$~,$#,);$,++
;$,++;$^|=$";`$_$\$,$/$:$;$~$*$%[$?]$.$~$*${#}$%[$?]$;$\$"$^$~$*.>&$=`
 
J

jai_guevara

Thanks for the replies. I can't believe I haven't seen this before. It
makes sense, but it's still weird for a language like Perl. I usually
expect a higher-level programming language to insulate me from the
gritty details of binary arithmetic.

Also, please excuse the weird spelling. What happened to "I before E
except after C"? I must have skipped the day they covered exceptions.
 
R

robic0

Thanks for the replies. I can't believe I haven't seen this before. It
makes sense, but it's still weird for a language like Perl. I usually
expect a higher-level programming language to insulate me from the
gritty details of binary arithmetic.

Also, please excuse the weird spelling. What happened to "I before E
except after C"? I must have skipped the day they covered exceptions.
Except for weird, because wierd is too dyslexic for most and looks
like "wire". But thats English.
 
T

Tad McClellan

I usually
expect a higher-level programming language to insulate me from the
gritty details of binary arithmetic.


How did you come to have that expectation?

Have you used a few languages that did that for you?

Could you name an example to help enlighten us?
 
P

poopdeville

Tad said:
How did you come to have that expectation?

Have you used a few languages that did that for you?

Could you name an example to help enlighten us?

Mathematica does it. It obviously can't do it in every case, but it
handles all the cases I've asked it to.

'cid 'ooh
 
J

jai_guevara

Sure. This problem got me to thinking, so here are some examples.

perl -e "print 17.50-18.30"
-0.800000000000001
awk 'BEGIN {print 17.50-18.30}'
-0.8
python -c "print 17.50-18.30"
-0.8
t.c: main() { printf("%f\n", 17.50-18.30); }
cc t.c; a.out
-0.800000
mysql -Ne "select 17.50-18.30"
+-------+
| -0.80 |
+-------+
 
D

Dr.Ruud

(e-mail address removed):
Sure. This problem got me to thinking, so here are some examples.

perl -e "print 17.50-18.30"
-0.800000000000001

That just shows that the DBL_DIG macro from float.h returned 15.
See perldoc perlvar, look for "printed numbers".


$ perl -e '$#="%.6g"; print(17.5-18.3)'
-0.8

$ perl -e '$#="%.20g"; print(17.5-18.3)'
-0.80000000000000071054


$ perl -e 'print(1/3)'
0.333333333333333

$ perl -e '$#="%.99g"; print(1/3)'
0.333333333333333314829616256247390992939472198486328125
 
B

Bill Ricker N1VUX

[With a courtesy carbon to
Also, please excuse the weird spelling.
:)

What happened to "I before E
except after C"? I must have skipped the day they covered exceptions.

My dad learned a nonsense "sentence" as mnemonic for the major exceptions in
his one-room schoolhouse during the Great Depression :

"Neither leisured foreigner seized their weird heights."

That's not all, but most of the rest are "represented" there.

We can ignore as "obvious" words that have a syllable break between E and I --
which should have a diersis but no longer get one -- like "agreeing". Some
other words are included by analogy in the above "sentence".

But we can use Perl and be explicit.

perl -nle "print if /[^c]ei/" /usr/dict/words

gives us three types of words -- those with root/stems in the above sentence
(ignore), and the following roots/stems:

beige, counterfeit, forfeit, heifer, heinous, heir, protein, reign, rein,
seismic, veil, vein
-- are these stealth bi-syllabic? French? Dutch?

deign, feign, freight, neigh, neighbor, reign, sleigh, weigh[t]
-- before silent g, as Foreign and height, probably taking the spelling
from the Dutch of the imported typesetters working for Caxton, first English
printer (1476CE).

From this we can conclude
Orthography recapitulates Etymology.

Note -- if you don't have /usr/dict/words on your Wintel PC, you can download
it
[eg http://minnie.tuhs.org/UnixTree/V7/usr/dict/words.html]
and mkdir c:\usr and c:\usr\dict so it just works, even with forward slashes.
(Or put it at D:\usr\dict\words, if $HOME is on D:\)

More dictionaries are linked from
http://www.puzzlers.org/dokuwiki/doku.php?id=misc:dictionaries
I use these dictionaries and Perl to "cheat" at NPR WESun word puzzles.
http://boston.pm.org/kwiki/index.cgi?BillRicker

cheers,

Bill aka n1vux
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,176
Messages
2,570,947
Members
47,501
Latest member
Ledmyplace

Latest Threads

Top