0

以下のPythonコードで何が起こっているのかを理解しようとしています。2 の平方根を取り、その小数を 1 で割ります。これを 5 回繰り返しても同じ値が得られますが、6 回目と 7 回目では異なる値が得られます。

入力値が前の 5 つの計算と同じであるのに、6 回目に出力が変化するのはなぜですか?

import math as M
frct = M.sqrt(2)

# 1
frct = 1 / (frct - int(frct))
print frct # 2.41421356237

# 2
frct = 1 / (frct - int(frct))
print frct # 2.41421356237

# 3
frct = 1 / (frct - int(frct))
print frct # 2.41421356237

# 4
frct = 1 / (frct - int(frct))
print frct # 2.41421356237

# 5
frct = 1 / (frct - int(frct))
print frct # 2.41421356237

# 6
frct = 1 / (frct - int(frct))
print frct # 2.41421356238

# 7
frct = 1 / (frct - int(frct))
print frct # 2.41421356235
4

2 に答える 2

9

短いバージョン、Pythonは出力を丸めています:)

import math as M
frct = M.sqrt(2)

for i in range(7):
    frct = 1 / (frct - int(frct))
    print 'Attempt %d: %.20f' % (i, frct)

長いバージョンのフローティングポイントは、実際の(しゃれを意図していない)値を格納せず、指数と仮数を格納します。詳細については、このウィキペディアのページを参照してください:http: //en.wikipedia.org/wiki/Floating_point

基本的に、浮動小数点数は次のように格納されます。

Significant digits × base^exponent

Pythonでより正確なバージョンが必要な場合は、decimalモジュールを試してください。

import decimal
context = decimal.Context(prec=100)
frct = context.sqrt(decimal.Decimal(2))

print 'Original square root:', frct

for i in range(7):
    frct = context.divide(1, frct - int(frct))
    print 'Attempt %d: %s' % (i, frct)

出力:

Original square root: 1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641573
Attempt 0: 2.414213562373095048801688724266222622763067167798368627068136427003657772608039155697953022512189319
Attempt 1: 2.414213562373095048801688723683379910288448158038030882339615025168647691299718507620657724911891709
Attempt 2: 2.414213562373095048801688727180436185136162216600057354932063779738350752352175486771948426117071942
Attempt 3: 2.414213562373095048801688706780941248524496874988236407630784335182989956231878308913506955872772859
Attempt 4: 2.414213562373095048801688825680854593346774866097140494471009059332623720827093783193465943198777227
Attempt 5: 2.414213562373095048801688132680869461024772261055702548455940065126184103929661474210576202848416747
Attempt 6: 2.414213562373095048801692171780866910134509900201052604731129303452089934643341550673727041448985316
于 2013-01-30T23:22:17.423 に答える
3

print frctstr(frct)は、数値を正確に再現するために必要な有効桁数よりも少ない有効桁数を示しています。に置き換えるprint frctprint repr(frct)、最初の5回は数値が同じではなく、丸められた表現が同じままになるのに十分ゆっくりと(最初は)変化することがわかります。

2.4142135623730945
2.4142135623730985
2.414213562373075
2.414213562373212
2.4142135623724124
2.414213562377074
2.414213562349904
于 2013-01-30T23:17:18.333 に答える