SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

Python 3.0開発者ガイド:数値、文字列、データ

数値、文字列、バイナリデータの基本データ型の処理

  • X ポスト
  • このエントリーをはてなブックマークに追加

浮動小数点数の改善点

 却下されたPEP-754では、PythonのIEEE 754完全準拠が提案されていました。これが却下されたのは、NaN(非数)や正負の無限大など、IEEE 754特殊値を処理するのに、Python(CPython実装)がCライブラリに依存しているためです。異なるプラットフォーム間に多くの不整合があります。それでも、Python 3.0では(2.6でも)浮動小数点数に多くの改良が加えられ、IEEE 754標準の実装も大幅に進みました。

 文字列を浮動小数点数に変換するfloat()関数は、nan+inf(またはinf)、および-infを認識し、IEEE 754の非数、正の無限大、負の無限大に変換するようになりました(大文字小文字は区別されず、NaNINFなども有効です)。

 mathモジュールに、isnan()関数とisinf()関数が追加されました。isinf()関数では、inf+inf-infは区別されません。以下に使用例を示します。

>>> float('nan')
nan

>>> float('NaN') # Any case works
nan

>>> float('+inf')
inf

>>> float('-inf')
-inf

>>> float('INF')
inf

>>> float('nan') + float('inf')
nan

>>> float('inf') + float('-inf')
nan

>>> float('inf') - float('-inf')
inf

>>> import math
>>> math.isnan(float('nan'))
True

>>> math.isinf(float('inf'))
True

>>> math.isinf(float('-inf'))
True

>>> math.isinf(float('nan'))
False

>>> math.isnan(float('-inf'))
False

 mathモジュールには、copysign(x, y)関数も追加されました。この関数は、xの絶対値に符号yを付けて返します。-1と1を返す単純なsign()や、ispositive()isnegative()といった関数ではなく、どうしてこの関数なのか、よく分かりません。ドキュメントにもごく簡潔な記述しかありません。

>>> help(math.copysign)
Help on built-in function copysign in module math:

copysign(...)
    copysign(x,y)
    
    Return x with the sign of y.

 とはいえ、copysign()関数はこの説明のとおりに動作します。ただし、NaNの場合は別です。NaNの符号をコピーしようとした場合の結果は一貫せず、Mac OS Xでは負の符号、Windowsでは正の符号になります。クローズ済みのバグによると、この動作で問題なし、とされていますが、同意できません。NaNは非数なので、符号はありません。NaNから符号をコピーしようとすることは、数値ではないそれ以外の値(文字列、リスト、オブジェクト)から符号をコピーしようとするのと同じであり、例外を発生させるべきです。

 mathモジュールには、浮動小数点数関連の関数がこれ以外にも追加されています。math.fsum()は、繰り返し可能オブジェクト(iterable)から数値のストリームの合計を出す関数で、sum()組み込み関数とは異なり、部分合計による精度ロスを入念に回避しています。いずれかの数値がNaNの場合、結果はNaNになります。部分合計が+infまたは-infに達すると、sum()関数はそれを結果として返しますが、math.fsum()関数はOverflowError例外を発生させます。これは、よりIEEE 754に沿った動作です。

>>> sum([1e308, 1, -1e308])
0.0

>>> math.fsum([1e308, 1, -1e308])
1.0

>>> sum([1e100, 1, -1e100, -1])
-1.0

>>> math.fsum([1e100, 1, -1e100, -1])
0.0

>>> x = [1e308, 1e308, -1e308]
>>> sum(x)
inf

>>> math.fsum(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: intermediate overflow in fsum

>>> sum([float('nan'), 3.3])
nan

>>> math.fsum([float('nan'), -float('nan')])
nan

 acosh()関数、asinh()関数、atanh()関数は、逆双曲線関数を計算します。log1p()関数は1+x (base e)の自然対数を返します。trunc()関数は、数値の小数点以下を切り捨てて近似値の整数値を返します。

>>> math.acosh(30)
4.0940666686320855

>>> math.acosh(1)
0.0

>>> math.asinh(1)
0.88137358701954305

>>> math.asinh(0)
0.0

>>> math.atanh(0.5)
0.54930614433405489

>>> math.log1p(2)
1.0986122886681098

>>> math.trunc(-1.1)
-1
>>> math.trunc(-1.9)
-1
>>> math.trunc(1.1)
1
>>> math.trunc(1.9)
1
>>> math.trunc(3.0)
3

 浮動小数点数と16進文字列の間の変換を行うことができます。変換関数は、浮動小数点数を文字列表現へ、文字列表現を浮動小数点数へ変換し、10進と2進の変換の丸め誤差を発生させません(その数値を完全に表現する桁数がある場合)。floathex()メソッドは文字列を返し、float.fromhex()メソッドは文字列を(可能な限り正確に)数値に変換します。

>>> x = 4.2
>>> a.hex()
'0x1.0cccccccccccdp+2'
>>> float.fromhex('0x1.0cccccccccccdp+2')
4.2000000000000002

 decimalモジュールは汎用10進演算仕様バージョン1.66に更新されました。新しい機能として、exp()log10()などの基本的な算術関数のメソッドが追加されました。

>>> Decimal(1).exp()
Decimal("2.718281828459045235360287471")

>>> Decimal("2.7182818").ln()
Decimal("0.9999999895305022877376682436")

>>> Decimal(1000).log10()
Decimal("3")

 Decimalオブジェクトのas_tuple()メソッドは、符号、仮数、指数のフィールドを持つ名前付きタプルを返すようになりました(名前付きタプルについては今後の記事で説明します)。

>>> Decimal('-3.3').as_tuple()
DecimalTuple(sign=1, digits=(3, 3), exponent=-1)

 sysモジュールの新しい変数float_infoは、float.hファイルから得たプラットフォームの浮動小数点数サポート情報が含まれるオブジェクトです。

>>> sys.float_info
sys.floatinfo(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.2204460492503131e-16, radix=2, rounds=1)

 このように、Pythonの浮動小数点数サポートは確かに向上しましたが、まだ完璧ではありません。Pythonで重要な数値演算を行うには、Numpy外部パッケージが依然として最善の策と言えます。

次のページ
PEP 3141:数値の型階層

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Gigi Sayfan(Gigi Sayfan)

 主に大規模分散システムを対象とした、C/C++/C#/Python/Javaによるクロスプラットフォームのオブジェクト指向プログラミングに精通。現在は、Numenta社で脳の働きを模した人工知能システムの開発に取り組んでいる。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/4052 2009/06/29 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング