『Python数値計算ノート』ではアフィリエイトプログラムを利用して商品を紹介しています。

浮動小数点数(float)

【Python】倍精度実数型浮動小数点数(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 ビットで表現される倍精度実数型浮動小数点数です。
 
Pythonにおけるfloat(倍精度実数型浮動小数点数)
浮動小数点数についての細かな情報は、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'>

コメント

  1. HNaito より:

    「Python 数値解析」のタイトルページで、統計解析→「疑似乱数生成関数」 と 数学関数→「疑似乱数の生成」 ではタイトルが少し違うので内容が違うのかと思ってクリックしたのですが、同じページ ( 乱数の生成 ) の先頭へとんでいくので、少し紛らわしいかなと感じました。

    • あとりえこばと より:

      申し訳ないです。リンク先の重複に気づいていませんでした。数学関数の欄から「疑似乱数の生成」 を外し、統計解析の欄の一番上を「疑似乱数」としておきました。m(_ _)m

  2. あとりえこばと より:

    【AI連載小説】科学とコードの交差点(8)
     
    深夜、大学のラボで六郷開誠は物理学の数値計算に取り組んでいた。手前にはノートパソコンが開かれ、Pythonのエディタが起動していた。課題は数値計算の安定性に関するもので、特に浮動小数点数の挙動について深く理解する必要があった。

    開誠は最初に、浮動小数点数の仕組みや制約についての理論書を熟読した。彼は浮動小数点数が有限のビット数で表現されるため、精度の損失が発生しやすいことを理解した。誤差の起こり方や桁落ち、情報落ちなどについての知識が、今回の数値計算において不可欠であった。

    理論の理解を踏まえ、開誠はPythonのコードを書き始めた。彼は特に浮動小数点数を使った演算において注意が必要であることを理解し、数学的な演算において桁落ちや情報落ちが生じないよう慎重にプログラムを構築した。彼のコードでは、数学的な安定性を確保するために、演算の順序や精度管理に工夫を凝らしていた。浮動小数点数の特性を理解したことで、誤差が累積することを最小限に抑え、信頼性の高い数値計算が可能になった。

    開誠は友人やオンラインのフォーラムで議論し、Pythonの浮動小数点数における最適な手法や注意点を学びながら、その知識を実際の課題に活かしていった。彼が得た洞察や新しいアプローチは、同じ課題に取り組む仲間たちとの共有の場で鮮やかに輝いていた。