[英]How to bound a floating-point arithmetic result?
像x=a/b
这样的浮点运算通常不能精确表示,因此 CPU 必须进行舍入。 是否可以获得两个浮点数x_low
和x_up
,它们分别是最高浮点小于或等于a/b
的精确值和高于或等于a/b
的最低浮点?
一些条件是:
a
, b
, x_low
, x_up
和x
是float
a
和b
是正整数( 1.0f
, 2.0f
等)这会给你一个可能太大的界限:
#include <cmath>
#include <utility>
template<typename T>
std::pair<T, T> bounds(int a, int b) {
T ta = a, tb = b;
T ta_prev = std::nexttoward(ta), ta_next = std::nextafter(ta);
T tb_prev = std::nexttoward(tb), tb_next = std::nextafter(tb);
return std::make_pair(ta_prev / tb_next, ta_next / tb_prev);
}
一种简单的方法是以更高的精度进行除法并获得转换为浮点数的上限/下限:
struct float_range {
float lower;
float upper;
};
float_range to_float_range(double d) {
float as_float = static_cast<float>(d);
double rounded = double{as_float};
if (std::isnan(as_float) || rounded == d) {
// No rounding done
return { as_float, as_float };
}
if (rounded < d) {
// rounded down
return { as_float, std::nextafter(as_float, std::numeric_limits<float>::infinity()) };
}
// rounded up
return { std::nextafter(as_float, -std::numeric_limits<float>::infinity()), as_float };
}
float_range precise_divide(float a, float b) {
return to_float_range(double{a}/double{b});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.