The full text of the question: In which of the listed lines of code is there a potential logical error in the comparison of fractional numbers?

enter image description here

There may be several correct answers.

1) I do not really understand the question. What do they mean by "potential logical error"?

2) All the comparisons that I have checked checked http://ideone.com/xNE6TB is not true only the second line:

2-0.8 === 1+1.2 

But I understand that it is not true, not because there is a logical error, but stupidly different numbers come out comparing 1.2 and 2.2. But the answer is just the second line is not true. Help noob who than can with explanations.

  • var_dump(15/3 === 5.0); - Bookin
  • Both answered you brazenly deceived :) - Visman

2 answers 2

6/5 === 1.2

5 is not a power of 2, so the fraction is not exactly representable.
Compare for equality is not worth it.

2 - 0.8 === 1 + 1.2

Same as last time.
Plus, something these numbers are not equal at all.

abs (6/5 - 1.2) <0.0001

This is the correct form of checking the first equality.
Although I would put 1e-7 instead of 1e-4 .

1.2 === 1.2

In theory, the two literal constants are equal to each other. But it is strange.
Related question: Is it safe to compare == for double type?

0.0001> abs (6/5 - 1.2)

The correct form of comparison is !== for the first item.

  • var_dump(6 / 5 === 1.2); -> bool(true) , var_dump(1.2 === 1.2); -> bool(true) . - Visman
  • @Visman, question: "potential logical error" , i.e. that the two inaccurately represented numbers in this case do not match. It is important that they are not exactly representable, so there is a potential error here. - Qwertiy
  • In the second case ( 1.2 === 1.2 ) no, in the first I agree - there is. - Visman

In this case, floating-point numbers are used, in the documentation on the website about their accuracy there is even a section highlighted in red. These numbers do not have an exact internal representation and their accuracy is considered to be approximately up to the 14th decimal place. Further in the number can go any garbage, it can produce an unexpected result.

For example, the same comparison 6/5 === 1.2 , may well be represented in the memory as 6/5 === 1.2000000000000004 , and the result of the comparison as 1.19999999999998 == 1.2000000000000004 . Therefore, with such numbers need accuracy in circulation. As a rule, numbers are compared with any small difference abs(6/5 - 1.2) < 0.00001 . Comparing them with direct == or === is considered a logical error, since it is a time bomb.

Therefore, we obtain:

 6/5 === 1.2 - неверно 2-0.8 === 1+1.2 - спорно, но можно считать верным (всегда false) abs(6/5 - 1.2) < 0.0001 - верно 1.2 === 1.2 - неверно 0.0001 > abs(6/5 - 1.2) - верно 
  • "wrong" - these are the lines where there is a potential logical error, yes? Is 1.2 === 1.2 wrong precisely because floating point numbers are there too? - RoboNoob
  • @RoboNoob, yes, the lines with a potential logical error are marked as "invalid." Including check 1.2 === 1.2 although it will work in 99% of cases, but since there are floating point numbers, there is a chance to get a logical error. The fact is that this code can work normally, or it can stop working at some point (they changed the server, changed the PHP version, or simply the stars didn’t converge). No one guarantees the correctness of such a comparison of numbers, since after the 14th digit there may appear anything. - Alex Krass
  • var_dump(6 / 5 === 1.2); -> bool(true) , var_dump(1.2 === 1.2); -> bool(true) . - Visman
  • @Visman, read carefully the information on the provided links and learn mate. part, your true not guaranteed. The fact that you got a bool(true) is just a special case of probability and depends on the operating system and the implementation of the interpreter. Under certain conditions, you can safely catch bool(false) and the interpreter will be right. Even in the documentation about it specifically wrote and highlighted in red. - Alex Krass
  • one
    @Visman, let's say, but I get the same numbers float(0.8) and float(0.8) , but they are not equal. The same with 1.2 === 1.2 , they are equal only because the PHP source code has the same generation code. But there is no guarantee that one day this will not change in the source code. And if the interpreter suddenly starts issuing different sequences for two supposedly identical numbers for any reason, you cannot show anything to it. This is a potential mistake, a chance to encounter which tends to zero, but still a mistake. A rather narrow moment of theory for which practitioners do not care. - Alex Krass