node.js 和 python 中相同问题解决方案的不同结果

sou*_*ubi 3 javascript python bignum combinatorics arbitrary-precision

我用一些代码解决了以下 leetCode 问题:


你有d骰子,每个骰子都有f编号为 1、2、...、f 的面。

返回模 10^9 + 7 的可能方式数来掷骰子,使面朝上的数字总和等于t.


我制作了两个版本的解决方案代码,一个在 node.js 中使用mathjs,另一个在 python 中使用 math 模块。

在 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)
    )
);

Run Code Online (Sandbox Code Playgroud)

在蟒蛇中:

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))

Run Code Online (Sandbox Code Playgroud)

现在,当我使用这些参数运行代码时:d=30 f=30 t=500(每个版本代码的最后一行),我希望结果是222616187.

在 node.js 版本中,这正是我得到的。

但是在 python 版本中,我811448245.0不明白为什么会这样。

那么为什么结果会有差异呢?

Mis*_*agi 5

math模块使用float,而不是任意精度int

math - 数学函数

[...]

该模块提供以下功能。除非另有明确说明,所有返回值都是浮点数。

由于math.pow返回 a float, 的主要参数也%被转换为 a float。的结果dice(30, 30, 500)太大而无法准确表示为float。它的float表示由 关闭-14999044413600247749080617

**运营商和它的功能的版本operator.pow不强制float转换,并提供一个整数,如果所有的参数都是整数。

>>> print(dice(30, 30, 500) % (10 ** 9 + 7))
222616187
Run Code Online (Sandbox Code Playgroud)