繁体   English   中英

C 中的大数浮点除法

[英]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) 所以maxmax2都设置为 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM