谁能帮我为什么 x2 打印为零。我猜由于浮点表示 X1 被四舍五入,有没有办法保持进动。
long double x1, x2;
x1= 0.087912088; // Note: 360/4095 = 0.087912088
x2 = 360/4095;
printf("%Lf, %Lf \n",x1, x2);
结果:
x1 =0.087912
x2= 0.000000
谁能帮我为什么 x2 打印为零。我猜由于浮点表示 X1 被四舍五入,有没有办法保持进动。
long double x1, x2;
x1= 0.087912088; // Note: 360/4095 = 0.087912088
x2 = 360/4095;
printf("%Lf, %Lf \n",x1, x2);
结果:
x1 =0.087912
x2= 0.000000
问题是整数截断..你正在划分两个整数=>结果将是另一个整数,小数部分被丢弃。(例如,在整数除法的实际结果为 3.9 的情况下,截断将使其变为 3(即它不四舍五入))。
在您的情况下,如果您将其更改为:
x2 = 360 / 4095.0; /* one of the operands now has a decimal point */
你会得到
0.087912, 0.087912
作为输出。
即,只要除法运算符的一个或两个/
操作数都是浮点数/双精度数,结果也会是浮点数/双精度数(即,它将被“提升”为浮点数/双精度数)。所以我本可以x2
改为
x2 = 360.0 / 4095.0;
或者
x2 = 360.0 / 4095;
并且会得到与上面相同的结果。
正如@chris 所提到的,只使用 a.
也足够了。
关于您上面关于精度的问题:
您已经在使用长双打了.. 我不认为在内部您可以更改任何内容,除非您使用一些特殊的库,但您当然可以显示更多数字。例如,
printf("%Lf, %.20Lf \n",x1, x2);
将产生
0.087912, 0.08791208791208791895
最后,正如@edA-qa mort-ora-y 提醒我们的那样,您还可以将值强制转换为某些类型,但是当您这样做时很重要。一个简单的例子(请注意,在任何情况下,值都会在赋值float
之后v
结束,因为是 a float
):
float v = 0;
/* values shown are BEFORE assignment */
v = (5 / 2); /* value is 2 due to integer truncation before assignment */
v = (float) (5 / 2); /* 2.0 as integer division occurs 1st, then cast to float */
v = (float) 5 / 2; /* 2.5 since 5 becomes 5.0 through casting first. */
内置运算符适用于相同类型的对象。结果与参数的类型相同。在这种情况下,除法是对两个整数进行的,因此结果是一个整数。
x2 = 360/4096;
// int/int = int
因此,我期望结果为 0。
如果内置类型上的运算符不同,则将提升它们以使它们具有相同的类型(并且结果也是该类型)。所以你想要的是:
x2 = 1.0 * 360/4095; // or 360.0/4095
// This is
double * int / int
==> (double * double)/int
==> (double * double)/double