在 C 中将 float 表达式的结果存储到 int 变量中的正确方法是什么?

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)

处理这些案例的最佳做法是什么?

请注意,这个使用货币的示例只是一个示例。我想讨论一下一般情况。是否有进行此类操作的一般最佳实践?

klu*_*utt 7

\n

处理这些案例的最佳做法是什么?

\n
\n

当谈到货币时,最好的办法通常是不要使用浮动货币。使用整数。以下是货币浮动的一些问题:

\n
    \n
  • 大多数小数都无法准确表示

    \n
  • \n
  • 当数字变得太大时,浮点数会默默地失去最后整数位的精度

    \n
  • \n
\n

但仅仅使用整数是不够的。如果你只存储美分的数量,那么在进行利息等计算时可能会出现问题。相反,您想要存储例如数千美分。如果你愿意的话,一毫分。但请注意,这并不能自动解决所有问题。

\n

另请记住,存储毫分将需要非常大的整数。一个 32 位数字可以存储 40 亿毫分,相当于 40,000 美元。因此 64 位整数是首选。

\n

这是一篇文章,很好地描述了使用浮动货币的问题: https: //software.codidact.com/posts/284175

\n

引用上述链接中 celtschk 的回答:

\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
\n

正如 Eric Postpischil 在下面的评论中提到的:

\n
\n

\xe2\x80\x9cfix\xe2\x80\x9d 用于理解数学和表示类型的使用,并为特定情况设计软件。

\n
\n

如果我们讨论的不是货币,而是一般的“将 float 转换为 int”的情况,那么实际上就没有任何最佳实践。这一切都取决于个人情况。使用round通常会给出“更正确”的结果。

\n