C++ c++;sqrt保证精度,上限/下限
我必须检查一个包含平方根的不等式。为了避免由于浮点不准确和舍入而导致的错误结果,我使用C++ c++;sqrt保证精度,上限/下限,c++,c++11,floating-point,floating-accuracy,sqrt,C++,C++11,Floating Point,Floating Accuracy,Sqrt,我必须检查一个包含平方根的不等式。为了避免由于浮点不准确和舍入而导致的错误结果,我使用std::nextafter()来获取上限/下限: #include <cfloat> // DBL_MAX #include <cmath> // std::nextafter, std::sqrt double x = 42.0; //just an example number double y = std::nextafter(std::sqrt(x), DBL_MAX);
std::nextafter()
来获取上限/下限:
#include <cfloat> // DBL_MAX
#include <cmath> // std::nextafter, std::sqrt
double x = 42.0; //just an example number
double y = std::nextafter(std::sqrt(x), DBL_MAX);
#包括//DBL\u MAX
#包括//std::nextafter,std::sqrt
双x=42.0//只是一个例子
双y=std::nextafter(std::sqrt(x),DBL_MAX);
a) 使用GCC编译器是否保证y*y>=x
b) 这是否适用于其他操作,如+-*/
或甚至std::cos()
和std::acos()
c) 有没有更好的方法来获取上限/下限
更新:
这不是由C++标准保证的,而是应该按照IEEE-75标准来工作的。这是否适用于GCC编译器?对于GCC页面,如果您使用GCC内置sqrt函数\uuuuuuBuiltin\uSQRT
,它将起作用
此外,这种行为将取决于您如何编译代码以及运行代码的机器
-mfpmath=sse-msse2
编译代码,以确保使用sse寄存器完成所有浮点操作long double
类型作为浮点值,并使用标记-ffloat store
进行编译,以强制GCC不使用寄存器存储浮点值(这样做会导致性能损失)一般来说,浮点运算会导致一些错误。IEEE754要求大多数操作的结果在0.5ULP范围内是正确的,但误差可能会累积,这意味着结果可能不在精确结果的一个ULP范围内。精度也有限制,因此根据结果值中的位数,您也可能无法使用相同大小的值。超越函数在某种程度上也会在计算中引入误差 然而,如果您使用的是GNU,sqrt将正确到0.5 ULP(四舍五入),因此您可以使用特定的示例(忽略
NaN
,+/-0
,+/-Inf
)。不过,最好定义一些epsilon作为您的错误容忍度,并将其用作界限。对于exmaple
bool gt(double a, double b, double eps) {
return (a > b - eps);
}
根据计算中需要的精度级别,您可能还希望使用长双精度
所以,为了回答你的问题
a) 是否使用GCC编译器保证y*y>=x
假设您使用GNU glibc或SSE2内部函数,是的
b) 这是否适用于其他操作,如+-*/甚至std::cos()和std::acos()
假设您使用GNU glibc和一个操作,是的。虽然有些超验不能保证正确的四舍五入
c) 有没有更好的方法来获取上限/下限
您需要知道计算中的误差容限是多少,并将其用作ε(可能大于一个ULP)。
c) 有没有更好的方法来获取上限/下限
另一种方法是使用不同的,即
FE\u向上
或FE\u向下
,而不是默认的FE\u最短
。请看,这可能是,但是一个更好的上限/下限。您是要求此特定情况,还是一般要求任何浮点数?NaN马上就打破了任何逻辑。据我所知,标准没有对实现作出任何保证std::sqrt
,因此我认为这个问题的答案将取决于实现。@MarkB我是指任何(正)浮点数,42只是一个例子。您可能对此感兴趣(查找sqrt
)。