gpt4 book ai didi

c++ - 浮点计算使用 float 的结果与使用 double 的结果不同

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:56:47 26 4
gpt4 key购买 nike

我有以下代码行。

hero->onBeingHit(ENEMY_ATTACK_POINT * (1.0 - hero->getDefensePercent()));
  • void onBeingHit(int decHP) 方法接受整数并更新健康点数。
  • float getDefensePercent() 方法是一个返回英雄防御百分比的 getter 方法。
  • ENEMY_ATTACK_POINT 是定义为 #define ENEMY_ATTACK_POINT 20 的宏常数因子。

假设 hero->getDefensePercent() 返回 0.1。所以计算是

20 * (1.0 - 0.1)  =  20 * (0.9)  =  18

每当我尝试使用以下代码时(没有 f 附加 1.0)

hero->onBeingHit(ENEMY_ATTACK_POINT * (1.0 - hero->getDefensePercent()));

我得到了 17

但是对于下面的代码(1.0之后追加的f)

hero->onBeingHit(ENEMY_ATTACK_POINT * (1.0f - hero->getDefensePercent()));

我得到了 18

这是怎么回事?尽管 hero->getDefensePercent() 已经处于 float 状态,但 f 是否具有重要意义?

最佳答案

这是怎么回事?为什么在这两种情况下整数结果都不是 18

问题是浮点表达式的结果在转换为整数值时会向零舍入(在这两种情况下)。

0.1 不能精确表示为浮点值(在这两种情况下)。编译器将转换为二进制 IEEE754 float ,并决定是向上舍入还是向下舍入为可表示的值。然后处理器在运行时乘以这个值,结果四舍五入得到一个整数值。

好的,但是由于 doublefloat 的行为都是这样的,为什么在这两种情况之一中我得到 18 ,但在另一种情况下是 17 吗?我很困惑。

您的代码获取函数的结果 0.1f(一个 float ),然后计算 20 * (1.0 - 0.1f) 这是一个 double 表达式,而 20 * (1.0f - 0.1f) 是一个浮点表达式。现在 float 版本恰好略大于 18.0 并向下舍入为 18,而 double 表达式略小于 18.0 并得到向下舍入为 17

如果您不确切知道 IEEE754 二进制 float 是如何从十进制数构造的,那么如果它略小于或略大于您在代码中输入的十进制数,则这几乎是随机的。所以你不应该指望这个。不要试图通过将 f 附加到其中一个数字并说“现在它可以工作了,所以我把这个 f 留在那里”来解决这样的问题,因为另一个值的行为又不一样了。

为什么表达式的类型取决于此 f 的出现?

这是因为 C 和 C++ 中的浮点字面值默认为 double 类型。如果添加 f,它就是一个 float 。浮点表达式的结果是“更大”类型。 double 表达式和整数的结果仍然是 double 表达式,而 int 和 float 将是 float 。所以表达式的结果是 float 或 double 。

好的,但我不想四舍五入为零。我想四舍五入到最接近的数字。

要解决此问题,请在将结果转换为整数之前将结果加二分之一:

hero->onBeingHit(ENEMY_ATTACK_POINT * (1.0 - hero->getDefensePercent()) + 0.5);

在 C++11 中,有 std::round()为了那个原因。在标准的早期版本中,there was no such function to round to the nearest integer. (详情请见评论。)

如果没有std::round,可以自己写。处理负数时要小心。转换为整数时,数字将被截断(向零舍入),这意味着负值将向上舍入,而不是向下舍入。所以如果数字是负数,我们必须减去二分之一:

int round(double x) {
return (x < 0.0) ? (x - .5) : (x + .5);
}

关于c++ - 浮点计算使用 float 的结果与使用 double 的结果不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14890283/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com