C Format String printf("%lld") 错误结果
C Format String printf("%lld") wrong results
long long temp_number;
float input = 0.7f;
temp_number = input*100;
printf("%lld",temp_number);
谁能解释为什么我得到的是 69 而不是 70?
这里没有什么神秘的。它类似于将 1/3
写成小数 0.333333~
(~
表示 "recurring")然后乘以 3
。答案是0.999999~
而不是1
,我希望你能看到这与计算机科学无关。
您已将 float
转换为 long long int
,编译器警告说这样做可能会导致数据丢失。但是在转换为不同类型之前乘以 100,所以让我们再看一下 float
示例。
十进制值0.7
无法用二进制float
格式准确表示。当您将 printf
与 float
一起使用时,它会将尾数的最低有效位四舍五入以解决问题。所以当我这样做时
float f = 0.7f;
printf("%f\n", f);
输出是我想要的 0.700000
。但是,当我将 float
值乘以 100 时,这会在尾数的最低有效位中产生更大的错误,而之前只有 1
有错误。所以现在使用
float f = 0.7f;
printf("%f\n", f*100);
输出是 69.999999
,因为向上舍入最低有效位不会使数字累积到 70.000000
。
回到1/3
的十进制表示的第一个例子,但在有限的存储空间中,假设10位十进制数字为0.333333333
。乘以 3
得到 9.999999999
并且将最后一位四舍五入将得到 1.000000000
。但是乘以 30
得到 9.999999990
并且将最后一位四舍五入不会产生 10.00000000
.
C 语言不会 "know" 数字的 float
表示截断循环小数。也许有一种数值类型可以保存这些信息并相应地计算算术函数。
long long temp_number;
float input = 0.7f;
temp_number = input*100;
printf("%lld",temp_number);
谁能解释为什么我得到的是 69 而不是 70?
这里没有什么神秘的。它类似于将 1/3
写成小数 0.333333~
(~
表示 "recurring")然后乘以 3
。答案是0.999999~
而不是1
,我希望你能看到这与计算机科学无关。
您已将 float
转换为 long long int
,编译器警告说这样做可能会导致数据丢失。但是在转换为不同类型之前乘以 100,所以让我们再看一下 float
示例。
十进制值0.7
无法用二进制float
格式准确表示。当您将 printf
与 float
一起使用时,它会将尾数的最低有效位四舍五入以解决问题。所以当我这样做时
float f = 0.7f;
printf("%f\n", f);
输出是我想要的 0.700000
。但是,当我将 float
值乘以 100 时,这会在尾数的最低有效位中产生更大的错误,而之前只有 1
有错误。所以现在使用
float f = 0.7f;
printf("%f\n", f*100);
输出是 69.999999
,因为向上舍入最低有效位不会使数字累积到 70.000000
。
回到1/3
的十进制表示的第一个例子,但在有限的存储空间中,假设10位十进制数字为0.333333333
。乘以 3
得到 9.999999999
并且将最后一位四舍五入将得到 1.000000000
。但是乘以 30
得到 9.999999990
并且将最后一位四舍五入不会产生 10.00000000
.
C 语言不会 "know" 数字的 float
表示截断循环小数。也许有一种数值类型可以保存这些信息并相应地计算算术函数。