Zar*_*uta 3 c floating-point types
让我们考虑下面的代码:
#include <stdio.h>
int main()
{
float dollars;
int cents;
dollars = 159.95;
cents = dollars*100;
printf("Dollars:%f\tCents:%d\n",dollars,cents);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出将是:
Dollars: 159.949997 Cents:15995
Run Code Online (Sandbox Code Playgroud)
据我所知,159.95 没有精确的二进制表示。但我不确定为什么值 15995 存储在变量 cents 中。
我想知道在这些情况下是否需要在表达式中使用 round,这样:
cents = round(dollars*100);
Run Code Online (Sandbox Code Playgroud)
处理这些案例的最佳做法是什么?
请注意,这个使用货币的示例只是一个示例。我想讨论一下一般情况。是否有进行此类操作的一般最佳实践?
\n\n处理这些案例的最佳做法是什么?
\n
当谈到货币时,最好的办法通常是不要使用浮动货币。使用整数。以下是货币浮动的一些问题:
\n大多数小数都无法准确表示
\n当数字变得太大时,浮点数会默默地失去最后整数位的精度
\n但仅仅使用整数是不够的。如果你只存储美分的数量,那么在进行利息等计算时可能会出现问题。相反,您想要存储例如数千美分。如果你愿意的话,一毫分。但请注意,这并不能自动解决所有问题。
\n另请记住,存储毫分将需要非常大的整数。一个 32 位数字可以存储 40 亿毫分,相当于 40,000 美元。因此 64 位整数是首选。
\n这是一篇文章,很好地描述了使用浮动货币的问题: https: //software.codidact.com/posts/284175
\n引用上述链接中 celtschk 的回答:
\n\n\n例如,假设您投资了 128 美元,利息为 0.6%,但第一年您只能获得该百分比的一半。那么第一年能拿到多少钱呢?嗯,显然 128 美元的 0.3% 是 38.4 美分,然后四舍五入为 38 美分。但让我们以不同的方式进行计算:首先,我们计算您通常获得的利息:128 美元的 0.6% 为 76.8 美分,四舍五入为 77 美分。其中一半是 38.5 美分,四舍五入为 39 美分。这又多了一分钱。
\n为了避免这种类型的错误,中间计算应始终以更高的精度进行,并且仅将最终结果转换为经过适当舍入的整数分。
\n
*但没有任何规则是没有例外的。引用自这个答案:
\n\n\n举个例子,我曾经和一个程序员进行了长时间的讨论,他在软件计算风险中坚持用小数而不是浮点数来表示现金流。在簿记应用中,小数当然是唯一明智的选择(或整数),但对于使用大量随机模型和数值近似的风险管理,浮点数是正确的选择。
\n
正如 Eric Postpischil 在下面的评论中提到的:
\n\n\n\xe2\x80\x9cfix\xe2\x80\x9d 用于理解数学和表示类型的使用,并为特定情况设计软件。
\n
如果我们讨论的不是货币,而是一般的“将 float 转换为 int”的情况,那么实际上就没有任何最佳实践。这一切都取决于个人情况。使用round通常会给出“更正确”的结果。
| 归档时间: |
|
| 查看次数: |
849 次 |
| 最近记录: |