【发布时间】:2017-06-23 09:23:13
【问题描述】:
我想用 C++ 编写一个符合 IEEE-754 的除法,特别是关于除零处理:positive/0->Inf、negative/0->-Inf、everything else/0->NaN。
虽然我的机器上的一个简单的 C++ 除法会导致这种行为,但 C++ 标准并不强制要求这种语义。相反,它是未定义的,所以我不能依赖它。
那么在 C++ 中实现它的最快方法是什么?当然,我可以像这样进行显式测试:
double fdiv64(double numerator, double denominator)
{
using limits=std::numeric_limits<double>;
if (denominator==0.0) {
if (numerator>0.0) {
return limits::infinity();
} else if (numerator<0.0) {
return -limits::infinity();
} else {
return limits::quiet_NaN();
}
} else {
return numerator/denominator;
}
}
但这引入了额外的分支,在我的机器上完全是多余的,因为无论如何我都得到了正确的行为。似乎没有执行 IEEE-754 兼容划分的编译器内在函数。我可以使用内联汇编,但这也很不方便。
那么进行这种划分的最快方法是什么?
【问题讨论】:
-
语言标准不可能包括和跟踪IEEE-754标准。 stackoverflow.com/a/30245885/412080
-
在已经这样做的硬件上运行它。严重地。主流平台已经在做 AFAIK。
-
请注意,在可移植 C++ 中,您甚至不能假设浮点值的 格式 是 IEEE-754。
float可以是 42 位。因此,您天生就处于非便携式领域;唯一的问题是多远。 -
@gexicide 预期但例外。你不应该除以零。 IEEE-754 将这些值定义为 exceptional 并使用它们在下溢的情况下保留符号。您已经在以不合规的方式使用这些值。
-
您可以使用
std::numeric_limits<double>::is_iec559进行检查。 (IEC 559 是 IEEE 754 的别称)
标签: c++ division undefined-behavior ieee-754 divide-by-zero