假设我有一个无理数,例如\sqrt{3}
。由于它是非理性的,它没有十进制表示。所以当你试图用 IEEE 754 double 来表达它时,你会引入一个错误。
有很多数字的十进制表示是:
1.7320508075688772935274463415058723669428052538103806280558069794519330169088
00037081146186757248575675...
现在,当我计算时\sqrt{3}
,我得到1.732051
:
#include <stdio.h> // printf
#include <math.h> // needed for sqrt
int main() {
double myVar = sqrt (3);
printf("as double:\t%f\n", myVar);
}
根据Wolfram|Alpha,我有一个错误1.11100... × 10^-7
。
有什么办法可以自己计算错误吗?
(我不介意切换到 C++、Python 或 Java。如果没有简单的替代方案,我也可以使用 Mathematica)
澄清一下:我不想要只适用于 sqrt{3} 的解决方案。我想得到一个函数,它给我任何数字的错误。如果那不可能,我至少想知道 Wolfram|Alpha 如何获得更多价值。
我的尝试
在写这个问题时,我发现了这个:
#include <stdio.h> // printf
#include <math.h> // needed for sqrt
#include <float.h> // needed for higher precision
int main() {
long double r = sqrtl(3.0L);
printf("Precision: %d digits; %.*Lg\n",LDBL_DIG,LDBL_DIG,r);
}
有了这个,我可以2.0 * 10^-18
根据Wolfram|Alpha将错误归结为。所以我认为这可能足够接近来很好地估计错误。我写了这个:
#include <stdio.h> // printf
#include <math.h> // needed for sqrt
#include <float.h>
int main() {
double myVar = sqrt (3);
long double r = sqrtl(3.0L);
long double error = abs(r-myVar) / r;
printf("Double:\t\t%f\n", myVar);
printf("Precision:\t%d digits; %.*Lg\n",LDBL_DIG,LDBL_DIG,r);
printf("Error:\t\t%.*Lg\n", LDBL_DIG, error);
}
但它输出:
Double: 1.732051
Precision: 18 digits; 1.73205080756887729
Error: 0
我该如何解决这个错误?