

Pythonを学び始めたばかりなのですが、簡単な計算結果が正しくで出力されません。正確な計算にはなにか設定から間違えているのでしょうか。

[code]

    0.1 + 8.2
    
    8.299999999999999
    
[/code]


CC BY-SA 4.0
2023-09-11T14:38:40.347
96182
2023-09-12T02:54:16.170
2023-09-11T17:11:44.460
3060
59748
question
python
小数を含む値の加算を行うと、結果が意図した通りにならない


コンピュータ内の信号は `0` と `1` の組み合わせで構成されているということはご存じかと思いますが小数点数についてもそうです。 十進数の `0.1`
を二進数で表そうとすると `0.0001100110011001100...` と無限に続きます。
いわゆる[循環小数](https://ja.wikipedia.org/wiki/%E5%BE%AA%E7%92%B0%E5%B0%8F%E6%95%B0)です。
もちろんコンピュータ内での表現は有限の桁数しかありませんから完璧に表現することは出来ません。
計算の元になる値がそもそも正確に表現できていないわけで、これは[入力誤差](https://ja.wikipedia.org/wiki/%E6%95%B0%E5%80%A4%E8%A7%A3%E6%9E%90#.E5.85.A5.E5.8A.9B.E8.AA.A4.E5.B7.AE)と呼ばれる現象です。
もちろんこの誤差は計算結果にも伝播します。

[二進化十進表現](https://ja.wikipedia.org/wiki/%E4%BA%8C%E9%80%B2%E5%8C%96%E5%8D%81%E9%80%B2%E8%A1%A8%E7%8F%BE)などの工夫で誤差を抑えることは出来ますし、それを補助するライブラリもあるのですが……。
数値計算の精度については何か設定をしておけば問題なしというわけではなく諸々の事情が絡み合うので端的に説明することは出来ません。

Wikipedia
の[誤差](https://ja.wikipedia.org/wiki/%E8%AA%A4%E5%B7%AE)の項などは学習のとっかかりとしては有用かもしれません。


CC BY-SA 4.0
2023-09-11T19:15:02.903
96185
2023-09-11T19:15:02.903
3364
96182
answer


Pythonの数値型には `int`, `float`, `complex` があります  
参考: [数値型 int, float,
complex](https://docs.python.org/ja/3/library/stdtypes.html#numeric-types-int-
float-complex)

Pythonの **整数** 型 (`int`) には最大値がない・上限なしという特徴があるけれど,  
浮動小数点数は (普通に)浮動小数点処理ハードウェアを利用してるので他の言語や計算処理アプリと同様の特徴を持ちます  
(float と呼ばれてるが, CPythonでは C言語の `double`を使って実装)

[code]

    >>> n = 12345678901234567890123456789012345678901234567890
    >>> n
    12345678901234567890123456789012345678901234567890
    >>> type(n)
    <class 'int'>
    >>> f = 3.14
    >>> type(f)
    <class 'float'>
    
    >>> 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)
    
[/code]

参考ページに記されてるように 標準ライブラリーがあり, それらを使えば誤差は回避可能です

> (標準ライブラリには、さらに分数のための数値型 `fractions.Fraction` や、ユーザによる精度の定義が可能な浮動小数点数のための
> `decimal.Decimal` があります。)

* * *

#### 別のパッケージを使った例: sympy

`sympy`は 本来は方程式を解いたりするパッケージだけど  
ダミーで `x` を加えておいて, `x` を `0` に置き換えれば演算できます  
(`decimal.Decimal`を利用した演算などと比べ, 使いやすいパッケージ選ぶと良いでしょう)  
(探せば他に使いやすいパッケージ見つかるかもしれない)

[code]

    import sympy
    n, x, y = sympy.symbols('n x y')
    
    expr = 0.1 + 8.2 +x
    display(expr.subs(x, 0))
    
    # こちらでも可能
    expr = 1 / n + 82 / n
    expr.subs(n, 10)
    # 83/10
    
[/code]


CC BY-SA 4.0
2023-09-12T02:54:16.170
96189
2023-09-12T02:54:16.170
43025
96182
answer