[英]float division in C for large numbers
对于更大和更小的值,相同的操作似乎有所不同(我认为下面的代码比我用文字更好地解释了这个问题)我以相同的方式计算了 max 和 max3 ,只是值不同。 同样,我用不同的值以完全相同的方式计算了 max2 和 max4。 然而我得到的答案却大不相同?:
#include <stdio.h>
#include <math.h>
int main(void)
{
// 86997171 / 48 = 1812441.0625
int max = ceil((float) 86997171 / 48);
float max2 = ((float) 86997171)/ 48;
printf("max = %i, max2 = %f\n", max, max2);
int max3 = ceil((float) 3 / 2);
float max4 = ((float) 3) / 2;
printf("ma3 = %i, max4 = %f\n", max3, max4);
}
输出:
max = 1812441, max2 = 1812441.000000
ma3 = 2, max4 = 1.500000
我期待 max = 1812442, max2 = 1812441.062500 作为输出,因为原则上应该是这样。 现在我不知道该怎么办
C 中的大数浮点除法
这个问题与分裂无关。 舍入错误发生在初始转换为float
时。
在float
最常用的格式 IEEE-754 binary32 中,接近 86,997,171 的两个可表示数字是 86,997,168 和 86,997,176。 (这些是 10,874,746•2 3和 10,874,747•10 3 。10,874,746 和 10,874,747 是 24 位数字(需要 24 位二进制数字来表示它们),24 位是 binary32 格式用于表示浮点数的小数部分的全部- 点数。)
在这两个中,86,997,168 更接近。 因此,在(float) 86997171
中,86,997,171 被转换为 86,997,168。
那么 86,997,168 / 48 就是 1,812,441。 所以(float) 86997171 / 48
是 1,812,441, ceil((float) 86997171 / 48)
。 所以max
和max2
都设置为 1,812,441。
在 C 中, float
是一种单精度浮点格式,所以它通常是 4 个字节(在大多数编译器上),所以它的精度在 6-9 位有效数字左右,通常是 7 位数字。
您的号码1812441.0625
有 11 位数字,不适合float
型。
您应该改用double
,它在 C 中是一种双精度浮点格式,因此它通常为 8 个字节(在大多数编译器上),因此其精度约为 15-18 位有效数字,通常为 16 位数字,因此可以保持你的号码的精度。
事实上,在这种情况下使用double
会给出:
max = 1812442, max2 = 1812441.062500
ma3 = 2, max4 = 1.500000
这就是你需要的。
请注意,这些类型的精度在此处进行了说明。 这与事实相去甚远(如链接所解释的那样),但它为您的问题提供了很好的视角。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.