node.js 和 python 中相同问题解决方案的不同结果
Different results for the same problem solution in node.js and python
我用一些代码解决了以下 leetCode 问题:
您有 d
个骰子,每个骰子有 f
个编号为 1、2、...、f 的面。
Return 以 10^9 + 7 为模掷骰子的可能方式的数量,因此正面数字的总和等于 t
。
我制作了两个版本的解决方案代码,一个在 node.js 中使用 mathjs,另一个在 python 中使用数学模块。
在node.js
const { combinations: comb, bignumber: Big } = require("mathjs");
function dice(d, f, t) {
if (t > d * f || t < d) return 0;
var result = Big(0);
var i = 0;
var sign = 1;
var n = t - 1;
var k = t - d;
while (k >= 0 && i <= d) {
result = result.add(
comb(Big(d), Big(i))
.times(comb(Big(n), Big(k)))
.times(sign)
);
i++;
n -= f;
k -= f;
sign *= -1;
}
return result;
}
console.log(
dice(30, 30, 500).mod(
Big(10)
.pow(9)
.add(7)
)
);
在python中:
import math
def dice(d, f, t):
if t > d * f or t < d:
return 0
result = 0
i = 0
sign = 1
n = t - 1
k = t - d
while k >= 0 and i <= d:
result += math.comb(d, i) * math.comb(n, k) * sign
i += 1
n -= f
k -= f
sign *= -1
return result
print(dice(30, 30, 500) % (math.pow(10, 9) + 7))
现在当我 运行 带有这些参数的代码时: d
=30 f
=30 t
=500 (每个版本代码的最后一行), 我希望结果是 222616187
.
在 node.js 版本中,这正是我得到的。
但在 python 版本中,我得到 811448245.0
我不明白为什么会这样。
那么为什么结果会有所不同?
以一种奇怪的方式解决了。事实证明,math.pow returns 是一个浮点数而不是 int 并且不知何故被窃听了。我认为 int % float 中有一个不同的转换操作,并且被编译器区别对待。可以进一步调查。如果您将其转换为 int,这就是您的答案。
import math
def dice(d, f, t):
if t > d * f or t < d:
return 0
result = 0
i = 0
sign = 1
n = t - 1
k = t - d
while k >= 0 and i <= d:
result += math.comb(d, i) * math.comb(n, k) * sign
i += 1
n -= f
k -= f
sign *= -1
return result
print(dice(30, 30, 500) % int((math.pow(10, 9) + 7)))
math
模块使用float
,不是任意精度int
.
[...]
The following functions are provided by this module. Except when
explicitly noted otherwise, all return values are floats.
由于 math.pow
returns a float
,%
的前导参数也被转换为 float
。
dice(30, 30, 500)
的结果太大,无法准确表示为 float
。它的 float
表示被 -14999044413600247749080617
关闭。
**
运算符及其函数版本 operator.pow
不强制 float
转换并在所有参数均为整数时提供整数。
>>> print(dice(30, 30, 500) % (10 ** 9 + 7))
222616187
我用一些代码解决了以下 leetCode 问题:
您有
d
个骰子,每个骰子有 f
个编号为 1、2、...、f 的面。
Return 以 10^9 + 7 为模掷骰子的可能方式的数量,因此正面数字的总和等于 t
。
我制作了两个版本的解决方案代码,一个在 node.js 中使用 mathjs,另一个在 python 中使用数学模块。
在node.js
const { combinations: comb, bignumber: Big } = require("mathjs");
function dice(d, f, t) {
if (t > d * f || t < d) return 0;
var result = Big(0);
var i = 0;
var sign = 1;
var n = t - 1;
var k = t - d;
while (k >= 0 && i <= d) {
result = result.add(
comb(Big(d), Big(i))
.times(comb(Big(n), Big(k)))
.times(sign)
);
i++;
n -= f;
k -= f;
sign *= -1;
}
return result;
}
console.log(
dice(30, 30, 500).mod(
Big(10)
.pow(9)
.add(7)
)
);
在python中:
import math
def dice(d, f, t):
if t > d * f or t < d:
return 0
result = 0
i = 0
sign = 1
n = t - 1
k = t - d
while k >= 0 and i <= d:
result += math.comb(d, i) * math.comb(n, k) * sign
i += 1
n -= f
k -= f
sign *= -1
return result
print(dice(30, 30, 500) % (math.pow(10, 9) + 7))
现在当我 运行 带有这些参数的代码时: d
=30 f
=30 t
=500 (每个版本代码的最后一行), 我希望结果是 222616187
.
在 node.js 版本中,这正是我得到的。
但在 python 版本中,我得到 811448245.0
我不明白为什么会这样。
那么为什么结果会有所不同?
以一种奇怪的方式解决了。事实证明,math.pow returns 是一个浮点数而不是 int 并且不知何故被窃听了。我认为 int % float 中有一个不同的转换操作,并且被编译器区别对待。可以进一步调查。如果您将其转换为 int,这就是您的答案。
import math
def dice(d, f, t):
if t > d * f or t < d:
return 0
result = 0
i = 0
sign = 1
n = t - 1
k = t - d
while k >= 0 and i <= d:
result += math.comb(d, i) * math.comb(n, k) * sign
i += 1
n -= f
k -= f
sign *= -1
return result
print(dice(30, 30, 500) % int((math.pow(10, 9) + 7)))
math
模块使用float
,不是任意精度int
.
[...]
The following functions are provided by this module. Except when explicitly noted otherwise, all return values are floats.
由于 math.pow
returns a float
,%
的前导参数也被转换为 float
。
dice(30, 30, 500)
的结果太大,无法准确表示为 float
。它的 float
表示被 -14999044413600247749080617
关闭。
**
运算符及其函数版本 operator.pow
不强制 float
转换并在所有参数均为整数时提供整数。
>>> print(dice(30, 30, 500) % (10 ** 9 + 7))
222616187