Hello all,
First time posting here, let me know if there is a better place for this kind of question
I am seeing non-deterministic behavior when summing f32
values, and am looking for best practice/advice for how to deal with this. I am working on some machine learning algorithms in rust, as side projects. I am using f32
values as this is fairly common in these algorithms for speed. However, I am seeing depending on how I sum a vector of f32
values, I get different results.
For example...
let records = 300000;
let vec = vec![0.23500371; records];
println!("Sum Result: {}", vec.iter().sum::<f32>());
// Sum Result: 70366.76
Now the same value, using multiplication to simulate summing.
println!("Multiplication Results {}", vec[0] * (records as f32));
// Multiplication Results 70501.11
Finally, summing, but chunks of the vector, and then summing those values. This is to mimic, sometimes I need to sum a vector by another vector, and I would expect the sub-sums summed together would equal the same as summing the entire vector, but again different results...
let chunks = vec.chunks_exact(10);
let remainder = chunks.remainder().to_vec();
assert!(remainder.is_empty());
let vec_c = chunks.map(|v| v.iter().sum::<f32>()).collect::<Vec<f32>>();
println!("Batch sum Result: {}", vec_c.iter().sum::<f32>());
// Batch sum Result: 70521.31
Here is the link to this in the playground.
I am OK, with the fact that there is going to be differences between these operations for instance between a f32
or a f64
, just because of precision, but it seems summing chunks of a vector, and then for instance summing the same vector in it's entirety should produce the same results? This is probably just my lack of knowledge around how floating point numbers work in rust.
Is there anything I can do, or pre-processing of the numbers to ensure these different operations will produce the same results?