"""
浮動小数点数の連続加算結果の整数変換に関する挙動を確認するスクリプト。
浮動小数点数の精度誤差により、意図しない整数変換が行われる可能性があることを示します。
`h` を `n` 回加算した結果 `v` を、通常の `int(v)` と微小な `eps` を加算した `int(v + eps)`
の両方で比較し、その違いを観察します。
:doc:`bad_int_usage`
"""
import sys
#===================
# parameters
#===================
h = 0.01
n = 100
eps = 1.0e-10
[ドキュメント]
def getintarg(iarg, defval = None):
"""
コマンドライン引数から指定されたインデックスの値を整数に変換して取得します。
変換に失敗した場合(例: 引数が存在しない、または整数に変換できない場合)は、
`defval` で指定されたデフォルト値を返します。
:param iarg: int 引数のインデックス。
:param defval: int, optional 変換失敗時に返すデフォルト値。デフォルトはNone。
:returns: int または None 変換された整数値、またはデフォルト値。
"""
try:
return int(argv[iarg])
except:
return defval
[ドキュメント]
def getfloatarg(iarg, defval = None):
"""
コマンドライン引数から指定されたインデックスの値を浮動小数点数に変換して取得します。
変換に失敗した場合(例: 引数が存在しない、または浮動小数点数に変換できない場合)は、
`defval` で指定されたデフォルト値を返します。
:param iarg: int 引数のインデックス。
:param defval: float, optional 変換失敗時に返すデフォルト値。デフォルトはNone。
:returns: float または None 変換された浮動小数点数値、またはデフォルト値。
"""
try:
return float(argv[iarg])
except:
return defval
argv = sys.argv
narg = len(argv)
if narg <= 2:
print("")
print("Usage: python bad_if.py h n answer")
print(" Check interger conversion of the summation of h for n times")
print("")
exit()
else:
h = getfloatarg(1, h)
n = getintarg(2, n)
#===================
# main routine
#===================
v = 0.0
for i in range(n):
v += h
print("")
print(f"Summing up {h} for {n} times: v = {v}")
print(f"int({v}) = {int(v)}")
print(f"int({v} + {eps}) = {int(v + eps)}")
print("")