(楼层)如何在C中工作?乘以100并调用(floor)

时间:2017-06-12 15:15:25

标签: c integer cs50 floor

(楼层)如何在C中实际运作? 据techonthenet说。 com,

  

在C编程语言中,floor函数返回最大值   小于或等于x的整数(即:舍入为x   最接近的整数)。

将值4.2输入get_float()后, 我使用floor(4.2 * 100),将它们变成美分并删除小数位并将其变成整数。

但是,我很困惑为什么专门输入值4.2会为楼层(4.2 * 100)和楼层(4.2 * 1000/10)返回不同的值? 这与不精确有关吗?

见图片: When variable entered as 4.2, floor produces different values

顺便说一下,我刚刚开始使用edx上的CS50,并且尝试了第1周课程的最后一次练习..也会喜欢对代码其他部分的任何评论。 有关此问题的更多信息: http://docs.cs50.net/problems/greedy/greedy.html

3 个答案:

答案 0 :(得分:2)

  

这与不精确有关吗?

它与不精确有关。

您不能用有限的位数表示无限数量的浮点值,因此实际存储在浮点类型中的是大多数值的近似值4.2无法在32位float类型中以完全表示;实际存储的内容更接近4.199999809你需要48位有效数字来表示它,这意味着你需要使用64位double

= sigh = 我无法添加。 double让你更接近4.2,但不完全正确。

这只是谈论存储,而不是关于算术运算中的舍入和错误传播。

通常,使用double代替float进行浮点工作(更大范围的精度)会更好。此外,最好将货币金额存储在整数类型中,并缩放到最小单位(例如,而不是存储4.2美元,存储420美分或4200密耳)。您仍然需要使用浮点类型来计算兴趣和类似的东西,但是在进行适当的舍入和缩放之后,您希望这些结果存储回整数类型。

答案 1 :(得分:1)

float/double无法准确表示所有可能的数字。典型的float可代表约2 32 不同的数字。 4.2不是其中之一。而是使用最近的值。打印using FLT_DECIMAL_DIG以查看数字的足够精确度,以确定它不完全是4.2

#include <float.h> 
float a = 4.2f;
printf("%.*e\n", FLT_DECIMAL_DIG-1, a);
// 4.19999981e+08

a *= 100;
printf("%.*e\n", FLT_DECIMAL_DIG-1, a);
// 4.19999969e+02

a = floor(a);
printf("%.*e\n", FLT_DECIMAL_DIG-1, a);
// 4.19000000e+02

使用a*100a*1000产品会产生四舍五入到最接近的可回答的答案并回想起来,a不是完全 4.2。

a = 4.2;
printf("%.*e\n", FLT_DECIMAL_DIG-1, a * 100);     // 4.19999969e+02
printf("%f\n", floor(a * 100));                   // 419.000000
printf("%.*e\n", FLT_DECIMAL_DIG-1, a * 1000);    // 4.20000000e+03
printf("%.*e\n", FLT_DECIMAL_DIG-1, a * 1000/10); // 4.20000000e+02
printf("%f\n", floor(a * 1000 / 10));             // 420.000000

使用floor()是一个不好的选择,当需要将数字四舍五入到最接近的0.01时,将4.2分成整数和分数。相反,使用匹配类型函数进行缩放,舍入然后分离。

  float a100 = a*100;
  printf("%.*e\n", FLT_DECIMAL_DIG-1, a100);    // 4.19999969e+02
  a100 = roundf(a100);
  printf("%.*e\n", FLT_DECIMAL_DIG-1, a100);    // 4.20000000e+02
  float a100th = fmodf(a100, 100);
  printf("%.*e\n", FLT_DECIMAL_DIG-1, a100th);  // 2.00000000e+01
  a = (a100 - a100th)/100;
  printf("%.*e\n", FLT_DECIMAL_DIG-1, a);       // 4.00000000e+00

Money 在C中有许多特殊问题,各种方法都有weaknesses。使用float是一个非常弱的选择。

答案 2 :(得分:0)

打印美元的价值,以便在尝试降低价值之前查看实际存储的内容。