Pure Programmer
Blue Matrix


Cluster Map

Project: Floating Point Error

Demonstrate the limitations of floating point math by computing 1/3 and storing it in a double variable. Then print the variable with 1/3 and the result of multiplying that variable by 3, 9 and 300 to sixteen decimal places. Do we get the exact results we expected? How do we get this result when 1/3 is infinitely repeating in its decimal form 0.3333...?

Try a similar experiment by assigning 0.2 to a variable. Then with a loop, add it 1000 times to another summation variable that was initialized with 0.0. Print the two-tenths variable, the final summation variable and the two-tenths variable times 1000, all to sixteen decimal places. Do we get the exact answer of 200.0 that we expect in both cases? Why does multiplication result in a better answer than repeated addition?

See [[Floating-point_arithmetic#Accuracy_problems|Floating Point Arithmetic Accuracy Problems]]

Output
$ rustc FloatingPointError.rs error: unknown format trait `f` --> FloatingPointError.rs:9:37 | 9 | println!("{}", format!("1/3: {0:.16f}", oneThird)); | ^ | = note: the only appropriate formatting traits are: - ``, which uses the `Display` trait - `?`, which uses the `Debug` trait - `e`, which uses the `LowerExp` trait - `E`, which uses the `UpperExp` trait - `o`, which uses the `Octal` trait - `p`, which uses the `Pointer` trait - `b`, which uses the `Binary` trait - `x`, which uses the `LowerHex` trait - `X`, which uses the `UpperHex` trait error: unknown format trait `f` --> FloatingPointError.rs:10:37 | 10 | println!("{}", format!("one: {0:.16f}", oneThird * 3.0f64)); | ^ | = note: the only appropriate formatting traits are: - ``, which uses the `Display` trait - `?`, which uses the `Debug` trait - `e`, which uses the `LowerExp` trait - `E`, which uses the `UpperExp` trait - `o`, which uses the `Octal` trait - `p`, which uses the `Pointer` trait - `b`, which uses the `Binary` trait - `x`, which uses the `LowerHex` trait - `X`, which uses the `UpperHex` trait error: unknown format trait `f` --> FloatingPointError.rs:11:39 | 11 | println!("{}", format!("three: {0:.16f}", oneThird * 9.0f64)); | ^ | = note: the only appropriate formatting traits are: - ``, which uses the `Display` trait - `?`, which uses the `Debug` trait - `e`, which uses the `LowerExp` trait - `E`, which uses the `UpperExp` trait - `o`, which uses the `Octal` trait - `p`, which uses the `Pointer` trait - `b`, which uses the `Binary` trait - `x`, which uses the `LowerHex` trait - `X`, which uses the `UpperHex` trait error: unknown format trait `f` --> FloatingPointError.rs:12:41 | 12 | println!("{}", format!("hundred: {0:.16f}", oneThird * 300.0f64)); | ^ | = note: the only appropriate formatting traits are: - ``, which uses the `Display` trait - `?`, which uses the `Debug` trait - `e`, which uses the `LowerExp` trait - `E`, which uses the `UpperExp` trait - `o`, which uses the `Octal` trait - `p`, which uses the `Pointer` trait - `b`, which uses the `Binary` trait - `x`, which uses the `LowerHex` trait - `X`, which uses the `UpperHex` trait error: unknown format trait `f` --> FloatingPointError.rs:23:43 | 23 | println!("{}", format!("twoTenths: {0:.16f}", twoTenths)); | ^ | = note: the only appropriate formatting traits are: - ``, which uses the `Display` trait - `?`, which uses the `Debug` trait - `e`, which uses the `LowerExp` trait - `E`, which uses the `UpperExp` trait - `o`, which uses the `Octal` trait - `p`, which uses the `Pointer` trait - `b`, which uses the `Binary` trait - `x`, which uses the `LowerHex` trait - `X`, which uses the `UpperHex` trait error: unknown format trait `f` --> FloatingPointError.rs:24:37 | 24 | println!("{}", format!("sum: {0:.16f}", sum)); | ^ | = note: the only appropriate formatting traits are: - ``, which uses the `Display` trait - `?`, which uses the `Debug` trait - `e`, which uses the `LowerExp` trait - `E`, which uses the `UpperExp` trait - `o`, which uses the `Octal` trait - `p`, which uses the `Pointer` trait - `b`, which uses the `Binary` trait - `x`, which uses the `LowerHex` trait - `X`, which uses the `UpperHex` trait error: unknown format trait `f` --> FloatingPointError.rs:25:37 | 25 | println!("{}", format!("200: {0:.16f}", twoTenths * 1000.f64)); | ^ | = note: the only appropriate formatting traits are: - ``, which uses the `Display` trait - `?`, which uses the `Debug` trait - `e`, which uses the `LowerExp` trait - `E`, which uses the `UpperExp` trait - `o`, which uses the `Octal` trait - `p`, which uses the `Pointer` trait - `b`, which uses the `Binary` trait - `x`, which uses the `LowerHex` trait - `X`, which uses the `UpperHex` trait error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields --> FloatingPointError.rs:8:27 | 8 | let mut oneThird:f64 = 1.f64 / 3.f64; | ^^^ | help: if intended to be a floating point literal, consider adding a `0` after the period | 8 | let mut oneThird:f64 = 1.0f64 / 3.f64; | + error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields --> FloatingPointError.rs:8:35 | 8 | let mut oneThird:f64 = 1.f64 / 3.f64; | ^^^ | help: if intended to be a floating point literal, consider adding a `0` after the period | 8 | let mut oneThird:f64 = 1.f64 / 3.0f64; | + error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields --> FloatingPointError.rs:25:59 | 25 | println!("{}", format!("200: {0:.16f}", twoTenths * 1000.f64)); | ^^^ | help: if intended to be a floating point literal, consider adding a `0` after the period | 25 | println!("{}", format!("200: {0:.16f}", twoTenths * 1000.0f64)); | + error: aborting due to 10 previous errors For more information about this error, try `rustc --explain E0610`.

Solution