What causes this strange Mathematica result?

I came across what seems like a mistake in Mathematica 8. I can’t find anything related to it on the Internet, but I admit that I’m not quite sure what to look for.

If I ran this statement:

0.05 + .10 /. {0.15 -> "pass"} 1.04 + .10 /. {1.14 -> "pass"} 1.05 + .10 /. {1.15 -> "pass"} 1.15 /. {1.15 -> "pass"} 

I get this output:

 pass pass 1.15 pass 

Am I just missing something?

Edit: After reading a useful discussion below, I modified the submit table to use the statement instead:

 f[x_] := Which[x == 1.05, -1.709847, x == 1.10, -1.373823, x == 1.15, -1.119214, x == 1.20, -0.9160143, x == 1.25, -0.7470223, x == 1.30, -0.6015966] 

This seems like a trick.

+4
source share
3 answers

Welcome to the world of precision machines. If you study 1.05 + 10 and 1.15 more closely, you will see that they are not exactly the same:

 1.05 + .10 // FullForm ==> 1.1500000000000001` 1.15 // FullForm ==> 1.15` 
+14
source

In addition to the small errors when using MachinePrecision , the same floating point calculation can give slightly different results at different times of the day. This is not a mistake, but rather a byproduct of how modern hardware floating point architectures work.

This means that you should not use operations such as ReplaceAll , which depend on knowing the exact value of MachinePrecision numbers. Using == (and === ) may be OK because they ignore the last 7 (respectively 1) binary digit of MachinePrecision .

Using mathematical mathematics should give accurate results regardless of the time of day, you can use it for your example as follows (10 significant digits)

 0.05`10 + .10`10 /. {0.15`10 -> "pass"} 1.04`10 + .10`10 /. {1.14`10 -> "pass"} 1.05`10 + .10`10 /. {1.15`10 -> "pass"} 1.15`10 /. {1.15`10 -> "pass"} 

Update : What every computer scientist needs to know about floating point arithmetic gives a few more warnings about floating point arithmetic. For example, on page 80 are examples of how different implementations of IEEE 754 give slightly different results, even despite the standard correspondence

+6
source

Your replacements work only for exact matches, while the While statement uses Equal . You can do rule-based work with Equal .

 0.05 + .10 /. {x_ /; x == 0.15 -> "pass"} 1.04 + .10 /. {x_ /; x == 1.14 -> "pass"} 1.05 + .10 /. {x_ /; x == 1.15 -> "pass"} 1.15 /. {x_ /; x == 1.15 -> "pass"} 
+4
source

Source: https://habr.com/ru/post/886434/


All Articles