Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Javascript';与C中的相同值相比,s Math.pow()似乎返回一个舍入值?_Javascript_C_Node.js_V8 - Fatal编程技术网

为什么Javascript';与C中的相同值相比,s Math.pow()似乎返回一个舍入值?

为什么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

我的理解是,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 = 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