Why does a1=72
instead of 73
in this (terrible) snippet of C++ code ?
#include <iostream>
#include <string>
using namespace std;
int main (int argc, char* argv[])
{
double a = 136.73;
unsigned int a1 = (100*(a-(int)a));
cout << (a-(int)a) << endl; // 0.73
cout << 100*(a-(int)a) << endl; // 73
cout << a1 <&开发者_运维百科lt; endl; // 72 !
}
You can execute it at http://codepad.org/HhGwTFhw
If you increase the output precision, you'll see that (a - (int) a)
prints 0.7299999999999898
.
Therefore, the truncation of this value (which you obtain when you cast it to an int
) is indeed 72
.
(Updated codepad here.)
This is a common precision issue. The literal 136.73
actually stands for the number
136.729999999999989768184605054557323455810546875
and the result of a-(int)a
is not 0.73
(even though that is what is displayed), but rather
0.729999999999989768184605054557323455810546875
When you multiply that by 100
, you get
72.9999999999989768184605054557323455810546875
And since converting from double to int cuts off everything after the decimal point, you get 72
.
0.73
cannot be represented exactly so it is rounded to a number close to it, which in this example is lower then 0.73
. when multiplying by 100, you get 72.[something]
, which is later trimmed to 72
.
more info
It might become clear if you read the following article: What Every Computer Scientist Should Know About Floating-Point Arithmetic.
The others have already shown that the result of (a - (int)a)
is not exactly 0.73, but a little lower. The article explains why that is so. It is not exactly an easy read, but really something everyone working with FP should read and try to understand, IMO.
精彩评论