On 22/08/2015 15:26, hw wrote: > > Hi, > > I have the following in a perl script: > > > if ($a != $b) { > print "e: '$a', t: '$b'\n"; > } > > > That will print: > > e: '69.99', t: '69.99' > > > When I replace != with ne (if ($a ne $a) {), it doesn't print. > > > Is that a bug or a feature? And if it's a feature, what's the explanation? > > And how do you deal with comparisions of variables when you get randomly > either correct results or wrong ones? It's randomly because this > statement checks multiple values in the script, and 69.99 is the only > number showing up yet which isn't numerically equal to itself (but equal > to itself when compared as strings).
Computer languages have a much more exact idea of what equality means than you do. In your head (because you are human, not silicon) you are completely comfortable with taking "69.99" and treat8ing it as a string, or a number, or a mostly-rounded-off floating point number. The computer does not do it like that. To a computer, the same must be exactly the same. Two things a little bit different are completely different (or not equal). And perl has two different operators for (in)equality: != does a numerical comparison. More on this below ne does a string comparison. When viewed as a bunch of characters, 69.99 and 69.99 are identical. Now, your comparisons are NOT random. They are entirely predictable, as long as you know what is going on; you are running into floating point numbers. And as it turns out, computers never represent these things exactly (they are NOT integers). Even though they look identical on-screen, in RAM they will not be (this must be so for perl to do the print). Maybe they actually resolve to 69.990000001 and 69.99000000. You see them as close-as-dammit equal, perl sees them as entirely different. This is such as huge IT problem that many solutions have been proposed. You get classes like BigFloat that represent a floating point as an integer so that equality works, you can round the floats off before comparing them, or just make the things integers. The last one is nice: don't represent money as dollars and cents, represent it as cents or decicents and only divide by 100 (or 1000) when you finally get to display it. So how to fix your problem: you are doing what you shouldn't do - trying equality on floats. Turn them into integers, or round them off, or use >=/<= instead of != -- Alan McKinnon alan.mckin...@gmail.com