1

私はdoctestをチェックアウトし、階乗の例をエディターにコピーしました。再帰を使うとより関数型プログラミングに感じられるので、例を次のように変更したいと思いました。

def factorial(n):
    # ... omitted
    if n+1 == n:  # catch a value like 1e300
        raise OverflowError("n too large")

    if n == 0:
        return 1
    else:
        return factorial(n  - 1) * n

この変更の後、テストの 1 つが失敗しました。

Failed example:
    factorial(30.0)
Expected:
    265252859812191058636308480000000L
Got:
    2.6525285981219103e+32

この違いの理由は何ですか?

4

2 に答える 2

5

factorial(30)の代わりにで実行してみてくださいfactorial(30.0)。浮動小数点の加算は整数の加算とまったく同じではないため、しばらくするとエラーが発生し始めます。

検討:

>>> 1e20 + 1 == 1e20 #True

これは、これらの数値の両方を一意に格納するのに十分な精度(ビット)がないためです。(典型的なpython floatは64ビットで、2 ** 64の一意の組み合わせがあります-オプションの周りのどこかに1.84e19あります。ただし、python floatの最大サイズはほとんどのシステムでsys.float_info.maxほぼ同じであるため、1.8e308各整数値を格納する方法はありません一意に-特にfloatが単なる整数値よりもはるかに多くを保持できることを考慮する場合)

個人的には、階乗は整数に対してのみ定義されているため、nの値を階乗関数内の整数にキャストします。おそらくabs(int(n) - n) < 1e-5、その効果を確認するためにチェックします。

于 2012-08-30T13:26:50.270 に答える
1

入力している数字はフロートです。intに変換していないので、出力にfloatが表示されます。

于 2012-08-30T13:26:42.133 に答える