gpt4 book ai didi

c++ - 浮点,相等比较是否足以防止被零除?

转载 作者:IT老高 更新时间:2023-10-28 21:45:18 31 4
gpt4 key购买 nike

// value will always be in the range of [0.0 - maximum]

float obtainRatio(float value, float maximum){
if(maximum != 0.f){
return value / maximum;
}else{
return 0.f;
}
}

maximum 的范围可以是任何值,包括负数。 value 的范围也可以是任何值,但仅当输入在 [0.0 - maximum] 的范围内时,该函数才需要“有意义”。输出应始终在 [0.0 - 1.0]

范围内

我有两个问题想问:

  • 这种相等比较是否足以确保函数永远不会被零除?
  • 如果最大值是退化值(极小或极大),函数是否有可能返回 [0.0 - 1.0] 之外的结果(假设值在正确范围内)?

最佳答案

这是一个较晚的答案,澄清了与该问题相关的一些概念:

只返回值/最大值

在 float 中,除以零并不是像整数除零那样的 fatal error 。由于您知道 value 介于 0.0maximum 之间,因此唯一可能发生的除零是 0.0 / 0.0 ,它被定义为产生 NaN 。浮点值 NaN 是函数 obtainRatio 返回的完全可接受的值,实际上是比 0.0 更好的异常值,因为您建议的版本正在返回。

关于浮点的迷信只是迷信

float 之间的 <= 的定义并不近似。当 a <= b 略高于 a 时, b not 有时评估为真。如果 ab 是两个有限的 float 变量,则当 a <= b 表示的有理数小于或等于 a 表示的有理数时,b 的计算结果为真。唯一可能察觉到的小故障实际上不是故障,而是对上述规则的严格解释:+0.0 <= -0.0 的计算结果为真,因为“+0.0 表示的有理数”和“-0.0 表示的有理数”都是 0。

同样, float 之间的 == 没有任何近似值:两个有限的 float 变量 ab 使 a == b 为真当且仅当由 a 表示的有理数和由 b 表示的有理数相同时

if (f != 0.0) 条件内,f 的值不能表示零,因此除以 f 不能除以零。除法仍然可以溢出。在 value / maximum 的特定情况下,不会出现溢出,因为您的函数需要 0 ≤ value ≤ maximum 。而且我们不需要怀疑前置条件中的是指有理数之间的关系还是 float 之间的关系,因为两者本质上是相同的。

这个说

C99 允许浮点表达式的额外精度,过去编译器制造商错误地将其解释为使浮点行为不稳定的许可证(以至于程序 if (m != 0.) { if (m == 0.) printf("oh"); } 可以在某些情况下应该打印“哦”)。

实际上,提供 IEEE 754 浮点并将 FLT_EVAL_METHOD 定义为非负值的 C99 编译器在经过测试后无法更改 m 的值。变量 m 在上次分配时被设置为一个可表示为 float 的值,该值要么是 0 的表示,要么不是。只有运算和常量可以有超额精度(参见 C99 标准,5.2.4.2.2:8)。

在 GCC 的情况下,最新版本执行 -fexcess-precision=standard 的正确操作,由 -std=c99 暗示。

进一步阅读

  • 几年前,David Monniaux 的 description 描述了 C 中浮点的可悲状态(第一个版本于 2007 年发布)。 David 的报告并没有试图解释 C99 标准,而是用真实的例子描述了当时 C 中浮点计算的现实。自那以后,情况有了很大改善,这要归功于关心的编译器提高了标准合规性,并且感谢 SSE2 指令集使整个问题变得毫无意义。

  • Joseph S. Myers 的 2008 mailing list post 描述了当时在 GCC 中使用 float 的 GCC 情况(差),他如何解释标准(好)以及他如何在 GCC 中实现他的解释(好)。

关于c++ - 浮点,相等比较是否足以防止被零除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23505212/

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