浮動小数点数 (floatオブジェクト)
Python で小数の計算を実行してみましょう。
# PYTHON_FLOAT
# In[1]
x = 0.2 + 0.6
print(x)
# 0.8
変数 x のデータ型を調べてみましょう。
# In[2]
# xのデータ型を調べる
print(type(x))
# <class 'float'>
0.8 は float とよばれるクラスに属していることがわかりました。float は floating point number の略語で、日本語では 浮動小数点数 とよばれます。浮動小数点数とは、ある数値の絶対値を
仮数×基数 指数
のように基数のベキ乗によって表現する数値型です。たとえば、$3500$ は
\[3.5 \times 10^3\]
のように表すことができます。$3500$ は
\[\begin{align*}0.35 \times 10^4\\[6pt]0.035 \times 10^5\\[6pt]0.0035 \times 10^6\end{align*}\]
のように、小数点の位置を変えて何通りにも同じ値を表すことができるので、浮動 (floating) という呼び名が与えられています。上の例では、わかりやすいように基数を $10$ としましたが、コンピュータの内部演算では $2$ を基数とする浮動小数点数が用いられます。
IEEE 754 形式 (IEEE Standard for Floating-Point Arithmetic) の浮動小数点数には、半精度浮動小数点数、単精度浮動小数点数など、いくつかの種類がありますが、Python の float は符号部 1 ビット、指数部 15 ビット、仮数部 52 ビットの計 64 ビットで表現される倍精度実数型浮動小数点数です。
浮動小数点数についての細かな情報は、sys.float_info で知ることができます。
# In[3]
import sys
sys.float_info
'''
sys.float_info(max=1.7976931348623157e+308,
max_exp=1024,
max_10_exp=308,
min=2.2250738585072014e-308,
min_exp=-1021,
min_10_exp=-307,
dig=15,
mant_dig=53,
epsilon=2.220446049250313e-16,
radix=2,
rounds=1)
'''
たとえば、radix は基数、max は float で表せる最大値、min は float で表せる最小値です。
リテラルで記述された小数には僅かな誤差があます。たとえば、float 型の 0.1 は厳密には 0.1 ではありません。0.1 を小数点以下 55 桁まで表示してみます。
# In[4]
format(0.1, '.55f')
# 0.1000000000000000055511151231257827021181583404541015625
ほとんどの 10 進数表記の小数は、2 進数表記に変換すると無限級数になってしまうので、コンピュータで処理するためには有限の桁で打ち切る必要があります。これが誤差を生む要因なのですが、誤差をなくすことは原理的に不可能とされています。それでも、Python の float型は、ほとんどの分野の計算において十分に実用的な精度をもっており、ソフトウェア開発で問題が顕在化することは稀です。ただし、会計アプリケーションなど、極めて高い精度が要求されるプログラムについては float型の代わりに Decimal型 を使ってください。
float.as_integer_ratio()
float.as_integer_ratio() は浮動小数点数を (分子, 分母) という有理数に変換してタプル形式で返します。
# PYTHON_FLOAT_INTEGER_RATIO
# In[1]
# 自然対数の底eの近似値
e = 2.71828182846
# eを分数に変換
x = e.as_integer_ratio()
print(x)
# (6121026514870223, 2251799813685248)
float.hex()
float.hex()は浮動小数点数を 16 進数表記の文字列に変換します。その値はメモリに保有される値の正確なコピーとなります。
# PYTHON_FLOAT_HEX
# In[1]
x = 2018.0
# xを16進数文字列に変換
y = x.hex()
print(y)
# 0x1.f880000000000p+10
# In[2]
print(type(y))
# <class 'str'>
p に続く数字は指数部を表しています。
float.fromhex()
float.fromhex() は 16 進数文字列を 10 進数浮動小数点数に変換します。
# PYTHON_FLOAT_FROMHEX
# In[1]
# 16進数文字列
x = "0x1.f880000000000p+10"
# 10進数の浮動小数点数に変換
y = float.fromhex(x)
print(y)
# 2018.0
# In[2]
print(type(y))
# <class 'float'>
「Python 数値解析」のタイトルページで、統計解析→「疑似乱数生成関数」 と 数学関数→「疑似乱数の生成」 ではタイトルが少し違うので内容が違うのかと思ってクリックしたのですが、同じページ ( 乱数の生成 ) の先頭へとんでいくので、少し紛らわしいかなと感じました。
申し訳ないです。リンク先の重複に気づいていませんでした。数学関数の欄から「疑似乱数の生成」 を外し、統計解析の欄の一番上を「疑似乱数」としておきました。m(_ _)m
【AI解説】Python の float とは?
[Q] Python の float はどのような原理に基づいて実装されていますか?
[ChatGPT] Pythonのfloat型は、浮動小数点数を表現するために使用されるデータ型です。Pythonのfloatは、IEEE 754倍精度浮動小数点数の実装に基づいています。IEEE 754は、浮動小数点数の表現と演算を標準化するための国際的な規格です。倍精度浮動小数点数は64ビット(8バイト)で構成され、以下の要素から成り立っています:
符号ビット(1ビット): 浮動小数点数が正または負の値を表すかを示す。
指数部(11ビット): 浮動小数点数の指数部を表現します。指数部は2の補数表現で表され、バイアス(bias)を使用してオフセットされます。
仮数部(52ビット): 浮動小数点数の実数部分を表現します。通常、1以上2未満の数であり、正規化された形式で表現されます。
Pythonのfloat型は、これらの要素を持つ64ビットのバイナリ形式で数値を表現します。また、特別な値として正の無限大、負の無限大、NaN(非数)なども表現できます。Pythonの浮動小数点数演算は、IEEE 754の演算ルールに従います。ただし、Pythonの浮動小数点数は厳密な数値表現ではなく、有限の精度しか持たないため、一部の計算で丸め誤差が発生することがあります。そのため、浮動小数点数の比較などの操作では、注意が必要です。Pythonのfloat型は、数値計算や科学技術計算など、様々な分野で広く使用されています。
[Q] float を使って誤差が生じる計算例を教えてください。
[ChatGPT] 浮動小数点数の誤差が生じる一般的な例の1つは、小数の精度が失われることです。浮動小数点数は有限のビット数で表現されるため、一部の小数は正確に表現できません。以下にいくつかの例を示します。
小数の加算:
- - - - - - - - - -
a = 0.1
b = 0.2
c = a + b
print(c)
# 結果は期待通りの0.3ではなく、0.30000000000000004となる場合があります
- - - - - - - - - -
この例では、0.1と0.2の加算結果が期待される0.3ではなく、微小な誤差が生じています。これは、浮動小数点数の二進表現において、一部の10進小数が正確に表現できないためです。
大きな数値の減算:
- - - - - - - - - -
a = 1e20
b = 1.0
c = a – b
print(c)
# 結果は期待通りの1e20ではなく、99999999999999991611392.0となる場合があります
- - - - - - - - - -
この例では、1e20と1.0の減算結果が期待される1e20ではなく、誤差が生じています。浮動小数点数の有効桁数により、大きな数値の差が正確に表現できなくなることがあります。
連続した演算の累積誤差:
- - - - - - - - - -
result = 0.1
for _ in range(10):
result += 0.1
print(result)
# 結果は期待通りの1.0ではなく、1.0000000000000002となる場合があります
- - - - - - - - - -
この例では、0.1を10回加算することで1.0が得られることが期待されますが、浮動小数点数の連続した演算により累積誤差が生じ、微小な差が発生します。
これらの例は、浮動小数点数の有限の精度により生じる一般的な問題を示しています。浮動小数点数を扱う際には、数値の比較や演算に対して誤差が生じる可能性を考慮し、適切な対策を講じることが重要です。