为什么Javascript';与C中的相同值相比,s Math.pow()似乎返回一个舍入值?
我的理解是,C的为什么Javascript';与C中的相同值相比,s Math.pow()似乎返回一个舍入值?,javascript,c,node.js,v8,Javascript,C,Node.js,V8,我的理解是,C的double和Javascript的数字都是IEEE 754 64位浮点数字。我试图将一些代码从C移植到Nodejs,但在Javascript的Math.pow()中遇到了一个舍入错误 这是我的C程序: #include "stdio.h" #include "math.h" int main(int argc, char *argv[]) { double shared = 729; double exponent = 15; double prime = 150
double
和Javascript的数字都是IEEE 754 64位浮点数字。我试图将一些代码从C移植到Nodejs,但在Javascript的Math.pow()
中遇到了一个舍入错误
这是我的C程序:
#include "stdio.h"
#include "math.h"
int main(int argc, char *argv[]) {
double shared = 729;
double exponent = 15;
double prime = 1500450271;
double power = pow(shared, exponent);
double mod = fmod(power, prime);
int intResult = (int) mod;
printf("shared: %lf, exponent: %lf, prime: %lf, pow: %lf, mod: %lf, result: %i\n",
shared, exponent, prime, power, mod, intResult);
}
其输出为:
shared: 729.000000, exponent: 15.000000, prime: 1500450271.000000, pow: 8727963568087711970669458465954849888403456.000000, mod: 1488486878.000000, result: 1488486878
有趣的是,当我尝试用Javascript(在node、Chrome、Firefox中测试)执行此计算时
我得到以下结果:
> Math.pow( 729, 15)
8.727963568087713e+42
> Math.pow( 729, 15 ) % 1500450271;
93655693
此外,当我将C的power结果存储在Javascript数字中时:
> 8727963568087711970669458465954849888403456.0
8.727963568087712e+42
请注意差异->8.727963568087713e+42!=8.727963568087712e+42
,因此可以理解,模运算无法产生相同的结果
我已经查看了v8实现Math.pow的源代码,但是masm宏在我看来像希腊语
感谢您的帮助。ECMAScript(“JavaScript”)不保证pow
函数的精度:
返回将x提高到y的幂的结果的依赖于实现的近似值
C语言也是如此。只有C99规范的可选附录F引用了IEC 60559(与IEEE 754相同),但是pow
不是精度保证的基本操作之一
在您的例子中,从Node.js得到的结果比从C程序得到的结果稍不准确,但这并不违反规范。您只需接受这种差异。无论如何,对大浮点数调用fmod
都是愚蠢的
编辑:产生差异的原因可能是x87 80位“双扩展”格式的精度过高。采取以下方案:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char *argv[]) {
int base = atoi(argv[1]);
int exp = atoi(argv[2]);
printf("pow: %.15e\n", pow(base, exp));
return 0;
}
使用-mpc64
编译:
$ gcc -mpc64 -Wall -O2 pow.c -lm -o pow
$ ./pow 729 15
pow: 8.727963568087713e+42
这与javascript中的以下内容类似:var x=0.1+0.1+0.1;控制台日志(x);它将打印0。30000000000000004@TomasMatejicek不,这只是普通的浮点限制。这里有两个实现在不同方面是不准确的。@delnan-不完全理解C版本是如何不准确的,你能详细说明一下吗?@dwerner我从来没有说过。两者都是近似值。重要的是,这些近似值是不同的。(是的,C代码的结果不正确,729**15=87279635680807712425891397479476727340041449。)@delnan-理解,谢谢delnan激发了我的理解,但能有问题背后的支持事实真的很棒。谢谢
$ gcc -mpc64 -Wall -O2 pow.c -lm -o pow
$ ./pow 729 15
pow: 8.727963568087713e+42