0.1 + 0.1 + 0.1 == 0.3 ?
パーフェクトPythonを写経中に0.1 + 0.1 + 0.1
について書いてあったのでメモ.
Pythonのfloat(浮動小数点数型)は、大抵の場合はCのdouble型を使って実装されており、近代的なコンピュータの場合53ビットの精度らしい.
$ python Python 2.7.3 (default, Feb 27 2014, 19:58:35) [GCC 4.6.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> 0.1 + 0.1 + 0.1 == 0.3 False >>> 0.1 + 0.1 + 0.1 0.30000000000000004
例が2系だけど3系でもFalseになる*1.
Pythonで0.1 + 0.1 + 0.1
を0.3
として扱いたい場合はdecimalモジュールをimportしてこれを用いれば良い.
$ irb irb(main):001:0> 0.1 + 0.1 + 0.1 == 0.3 => false
Rubyもfalse.
パーフェクトPythonでは、もう1つJavaを例として、0.1 + 0.1 + 0.1 == 0.3
がfalseになる様子が挙げられていたので、Cでも見てみた.
C
$ gcc -Wall test_double_dig.c
$ ./a.out
False:0.3000000000000000444089209850062616169452667236328125000000000000000000000000000000000000000000000000
詳しいことはWikipedia参照:コンピュータの数値表現
パーフェクトPython (PERFECT SERIES 5)
- 作者: Pythonサポーターズ
- 出版社/メーカー: 技術評論社
- 発売日: 2013/03/05
- メディア: 大型本
- 購入: 1人 クリック: 65回
- この商品を含むブログ (19件) を見る
世にも恐ろしいSIGPIPE、ソケットプログラミングの落とし穴
前回、「次回もシグナルのことを書く」と書いたのでシグナルのことを書く*1.
ソケットプログラミングの落とし穴は色々あるけど、ここでは個人的に嵌ったシグナル関連の落とし穴に関して書き殴る.
結論から書くと、コネクションが切れたソケットに書き込み(send(2)とかwrite(2)とか、同じものだけど)を行うと、SIGPIPEシグナルが発生してプロセスが強制終了するので、きちんとSIGPIPEシグナルをハンドリングしておこうという話.
以下では、サンプルコードを使って、実際にパイプの書き込み先をkillして、SIGPIPEの発生を疑似体験してみる.
*1:前回から115日が経っている.挫折したアドベントカレンダーもそうだけど、やはり連載宣言はするものじゃない.自分のような興味関心がブレまくる人間が連載宣言をしても、宣言した時をピークにモチベーションは下がり続ける.インプットのためのアウトプット、所詮メモの大原則を忘れている.