Recently, while organizing my notes, I discovered a strange issue:
The output of this code is:
0.1
1.2
2.3
3.4
4.5
5.6
6.7
7.8
8.9
100
1
2
3
4
5
6
7
8
9
The code is as follows:
1 | vector<double> testDouble; |
Why does the last pair of outputs show “10, 9”?
At first, I thought it was just an issue of converting double to int, and then tested:
1 | vector<double> test; |
The output was:
From the result, it seems it’s not just a conversion issue.
Now, we can infer from the latter results:
The element value 8.9
output earlier is not equal to the floating-point constant 8.9
After checking a lot of materials, I found out the root of the problem:
Precision issue
, the floating-point numbers in computers are not in decimal form, so it’s not possible to precisely add up to 10; the number is approximately 9.99999999999998 (it can output 10 due tofloating-point rounding
(IEEE 754)), and then when converted to int, it becomes 9 (truncated), which has nothing to do with the container or iterators.
Floating-point rounding
(excerpted from Wikipedia IEEE 754):
Round to nearest
: Round to the nearest value, with ties to even (Ties To Even, this is the default rounding method): it will round the result to the nearest representable value, but when two numbers are equally close, it takes the even one (which ends in 0 in binary).Round towards +∞
: it will round the result towards positive infinity.Round towards -∞
: it will round the result towards negative infinity.Round towards 0
: it will round the result towards 0.
Solution: Converting double to (forced conversion) int is truncation, and you can use the round function to round the values of type double
double round(double);
Testing the value assignment with round conversion (rounded up)
Let’s also test test.end()-1
and round(test.end()-1)
Conclusion: When encountering the need for forced data type conversion, you should pay close attention to the storage and computation methods of that type, and also take some time to review the IEEE standards.