Skip to main content
 首页 » 编程设计

java之Python之Java 数学运算给出不同的结果

2025年05月04日20jyk

我正在用 Java 和 Python 做一些大量的数学运算。总和相同,但结果不同。

python_n1 = int(math.floor(math.pow(int((int(361) * (int(4900 + 4489))) * int(4356)), int(6)))) 
BigInteger Java_n1 = (x[20].multiply(x[7].add(x[15])).multiply(x[10])).pow(6); 
 
python_simple_sum = 14764352724**6 #or math.pow(14764352724, 6) 
BigInteger Java_simple_sum = new BigInteger("14764352724 ").pow(6) 

Python 答案 = 10358251994780842724998096890217137953445700726699419360034816 Java 答案 = 10358251994780842575401275783021915748383652186833068257611776

Java 得到了正确的结果,但 python 却没有。据我所知,我没有使用 float 。这里有什么问题。

请您参考如下方法:

当你做的时候

int(math.pow(14764352724, 6)) 

你得到一个提升为幂的大数,但使用浮点方法,即使参数是整数也是如此。转换为整数会丢失精度(原始结果为 float :1.0358251994780843e+61)

当你做的时候

14764352724**6 

您可以使用仅使用整数乘法的二元幂方法将大数提升为幂。

所以第二个结果是准确的,而第一个不是

>>> int(math.pow(14764352724,6)) 
10358251994780842724998096890217137953445700726699419360034816   # wrong 
>>> 14764352724**6 
10358251994780842575401275783021915748383652186833068257611776   # correct 

让我们尝试反汇编 ** 和 math.pow 函数:

import dis,math 
 
def test(n): 
    return n ** 3 
 
def test2(n): 
    return math.pow(n,3) 
 
dis.dis(test) 
dis.dis(test2) 

输出

  4           0 LOAD_FAST                0 (n) 
              3 LOAD_CONST               1 (3) 
              6 BINARY_POWER 
              7 RETURN_VALUE 
 
  7           0 LOAD_GLOBAL              0 (math) 
              3 LOAD_ATTR                1 (pow) 
              6 LOAD_FAST                0 (n) 
              9 LOAD_CONST               1 (3) 
             12 CALL_FUNCTION            2 (2 positional, 0 keyword pair) 
             15 RETURN_VALUE 

如您所见,函数并不等同。 BINARY_POWER在第一种情况下被调用。 当参数为整数时,此函数有机会准确执行整数乘法:

BINARY_POWER()

Implements TOS = TOS1 ** TOS

当参数不全是整数时,二进制幂产生与 math.pow 相同的值:

>>> 14764352724**6.0 
1.0358251994780843e+61 
>>> int(14764352724**6.0) 
10358251994780842724998096890217137953445700726699419360034816 

注意:可能增加混淆的是内置的 pow方法,不同于math.pow (并在使用 from math import pow 时被后者覆盖),但在不使用模参数时等效于 ** 运算符:

pow(x, y[, z])

Return x to the power y; if z is present, return x to the power y, modulo z (computed more efficiently than pow(x, y) % z). The two-argument form pow(x, y) is equivalent to using the power operator: x**y.