Gentoo Archives: gentoo-user

From: hw <hw@×××××××××××××××××××××.de>
To: gentoo-user@l.g.o
Subject: Re: [gentoo-user] 69.99 != 69.99
Date: Sat, 22 Aug 2015 14:57:52
Message-Id: 55D88DE5.3040007@gartencenter-vaehning.de
In Reply to: Re: [gentoo-user] 69.99 != 69.99 by Alan McKinnon
1 Am 22.08.2015 um 15:43 schrieb Alan McKinnon:
2 > On 22/08/2015 15:26, hw wrote:
3 >>
4 >> Hi,
5 >>
6 >> I have the following in a perl script:
7 >>
8 >>
9 >> if ($a != $b) {
10 >> print "e: '$a', t: '$b'\n";
11 >> }
12 >>
13 >>
14 >> That will print:
15 >>
16 >> e: '69.99', t: '69.99'
17 >>
18 >>
19 >> When I replace != with ne (if ($a ne $a) {), it doesn't print.
20 >>
21 >>
22 >> Is that a bug or a feature? And if it's a feature, what's the explanation?
23 >>
24 >> And how do you deal with comparisions of variables when you get randomly
25 >> either correct results or wrong ones? It's randomly because this
26 >> statement checks multiple values in the script, and 69.99 is the only
27 >> number showing up yet which isn't numerically equal to itself (but equal
28 >> to itself when compared as strings).
29 >
30 >
31 >
32 > Computer languages have a much more exact idea of what equality means
33 > than you do. In your head (because you are human, not silicon) you are
34 > completely comfortable with taking "69.99" and treat8ing it as a string,
35 > or a number, or a mostly-rounded-off floating point number.
36 >
37 > The computer does not do it like that. To a computer, the same must be
38 > exactly the same. Two things a little bit different are completely
39 > different (or not equal). And perl has two different operators for
40 > (in)equality:
41 >
42 > != does a numerical comparison. More on this below
43 > ne does a string comparison. When viewed as a bunch of characters, 69.99
44 > and 69.99 are identical.
45
46 When the value is numerically not 69.99 but something like 69.99001,
47 then printing the value should print 69.99001 rather than 69.99.
48
49 perl -e 'print 1/3 . "\n";' prints 0.333333333333333
50
51 perl -e 'printf("%34.32f\n", 1/3);' prints
52 0.33333333333333331482961625624739
53
54 perl -e 'print (((1/3 == 0.333333333333333) ? "equal" : "not equal") .
55 "\n");' prints "not equal"
56
57 perl -e 'print (((1/3 == 0.0.33333333333333331482961625624739) ? "equal"
58 : "not equal") . "\n");' prints "Integer overflow in decimal number at
59 -e line 1." a couple times
60
61 This is random, may it be predictable or not, and what's the integer here?
62
63 > Now, your comparisons are NOT random. They are entirely predictable, as
64 > long as you know what is going on; you are running into floating point
65 > numbers. And as it turns out, computers never represent these things
66 > exactly (they are NOT integers). Even though they look identical
67 > on-screen, in RAM they will not be (this must be so for perl to do the
68 > print). Maybe they actually resolve to 69.990000001 and 69.99000000. You
69 > see them as close-as-dammit equal, perl sees them as entirely different.
70
71 Why can't it print the number as it is, or at least as it is compared,
72 like it should? If it would, one could see at once what the problem is.
73
74 > This is such as huge IT problem that many solutions have been proposed.
75 > You get classes like BigFloat that represent a floating point as an
76 > integer so that equality works, you can round the floats off before
77 > comparing them, or just make the things integers.
78 >
79 > The last one is nice: don't represent money as dollars and cents,
80 > represent it as cents or decicents and only divide by 100 (or 1000) when
81 > you finally get to display it.
82
83 That would add quite a lot of complexity, and the problem should either
84 be handled transparently, or the value should be printed as the
85 software/computer sees it. It is a recipe for disaster when you tell
86 your computer to print something but it prints something else instead.
87
88 > So how to fix your problem: you are doing what you shouldn't do - trying
89 > equality on floats. Turn them into integers, or round them off, or use
90 >> =/<= instead of !=
91
92 '=/<=' is not an operator in perl?

Replies

Subject Author
Re: [gentoo-user] 69.99 != 69.99 Franz Fellner <alpine.art.de@×××××.com>
Re: [gentoo-user] 69.99 != 69.99 Alan McKinnon <alan.mckinnon@×××××.com>
Re: [gentoo-user] 69.99 != 69.99 Paul Colquhoun <paulcol@×××××××××××××××××.au>
[gentoo-user] Re: 69.99 != 69.99 walt <w41ter@×××××.com>