Visual Studio 2019社区 float变量不是我初始化的对象。 为了避免截断,我降低了精确度。 这不是“可控的”吗?
试图以其他方式强制初始化
int main()
{
// where did my 6 go?
float b = 80.123456F;
printf("b:[%f]\n", b);
// rounds up
float c = 80.1234569F;
printf("c:[%f]\n", c);
// rounds up
float d = 80.1234561F;
printf("d:[%f]\n", d);
// appends a 1
float e = 80.12345F;
printf("e:[%f]\n", e);
// prints what's initialized
float f = 80.123451F;
printf("f:[%f]\n", f);
// prints what's initialized
float g = 80.123459F;
printf("g:[%f]\n", g);
}
b:[80.123459]
c:[80.123459]
d:[80.123459]
e:[80.123451]
f:[80.123451]
g:[80.123459]
我从调试器开始,并写了它以满足SO的要求。 就我而言,调试器匹配打印件
答案 0 :(得分:0)
浮点数最多只能精确到7个有效数字。不是7个十进制数字。 80.123456F有8位有效数字,所以这是行不通的。
80.12345只有7位有效数字,而实际上以80.1234512329101562结尾。只要您不尝试打印超出位数的数字,就可以了。不幸的是,%f总是在小数点后输出6位数字。在这种情况下,这不仅仅具有道理。您可以使用%g稍好一些,在那里您可以指定有效位数。
答案 1 :(得分:0)
两个问题:
printf
转换说明符的 %f
对其舍入的浮点值进行舍入以显示。您可以使用精度说明符控制显示小数点后的位数:printf( "%.8f\n", b );
将在小数点后最多显示8位数字,而printf( "%.16f\n", a);
将打印16位。不要相信显示的数字值,但是,因为...
无限数量的实数值不能容纳有限数量的位,因此大多数实数值不能精确表示为 -您得到的近似值仅适用于这么多的十进制数字。单精度float
类型的精度不能保证超过6到7个小数位数(不仅仅是小数点后的位数,而是总位数)。 double
为您提供10到11位数字。如果您需要用许多位数(大于12左右)表示值,则需要超越本机浮点类型并使用第三方多精度库。
答案 2 :(得分:0)
解决此问题的方法可能是更改数据类型。即使double
的操作方式与float
相同,并通过有限的一组有理数近似大范围的实数,但双精度值是如此接近,以至于舍入误差不太可能发生。>
例如,最接近实数80.123456的float
值是80.12345123291015625和80.1234588623046875。最接近80.123456的double
值是80.123456000000004451067070476710796356201171875和80.1234559999999902902123123747747070789337158203125。
float
确实有它的用途,在您要处理大量非常低的精度数字集的情况下,但是double
是更有用的类型。使用double
将物理量输入程序时,测量误差将超过舍入误差。