丸め誤差

大きな数どおしのわずかな差は,丸め誤差にとくに影響を受ける.

  1. 23.173-23.094 を有効数字がそれぞれ5桁,4桁,3桁,2桁で計算した結果を示せ.
  2. 同様に,0.81321/(23.173-23.094) を有効数字がそれぞれ5桁,4桁,3桁,2桁で計算した結果を示せ.
In [1]:
from decimal import *

def pretty_p(result,a,b,operator):
    print('context.prec:{}'.format(getcontext().prec))
    print(' %20.14f' % (a))
    print( '%1s%20.14f' % (operator, b))
    print('-----------')
    print( ' %20.14f' % (result))
In [2]:
getcontext().prec = 5

a=Decimal('0.81321')
b=Decimal('23.173')
c=Decimal('23.094')
pretty_p(b-c,b,c,'-')

a/(b-c)
context.prec:5
    23.17300000000000
-   23.09400000000000
-----------
     0.07900000000000
Out[2]:
Decimal('10.294')
In [3]:
TWOPLACES = Decimal(10) ** -2 
getcontext().prec = 4
a=Decimal('0.81321').quantize(Decimal(10) ** -4)
b=Decimal('23.173').quantize(Decimal('0.01'))
c=Decimal('23.094').quantize(Decimal('0.01'))

pretty_p(b-c,b,c,'-')
a/(b-c)
context.prec:4
    23.17000000000000
-   23.09000000000000
-----------
     0.08000000000000
Out[3]:
Decimal('10.16')
In [4]:
ONEPLACES = Decimal(10) ** -1
getcontext().prec = 3
a=Decimal('0.81321').quantize(Decimal(10) ** -3)
b=Decimal('23.173').quantize(ONEPLACES)
c=Decimal('23.094').quantize(ONEPLACES)

pretty_p(b-c,b,c,'-')
a/(b-c)
context.prec:3
    23.20000000000000
-   23.10000000000000
-----------
     0.10000000000000
Out[4]:
Decimal('8.13')
In [5]:
ZEROPLACES = Decimal(10) ** 0
getcontext().prec = 2
a=Decimal('0.81321').quantize(Decimal(10) ** -2)
b=Decimal('23.173').quantize(ZEROPLACES)
c=Decimal('23.094').quantize(ZEROPLACES)

pretty_p(b-c,b,c,'-')
a/(b-c)
context.prec:2
    23.00000000000000
-   23.00000000000000
-----------
     0.00000000000000
---------------------------------------------------------------------------
DivisionByZero                            Traceback (most recent call last)
<ipython-input-5-2050c7731b85> in <module>()
      6 
      7 pretty_p(b-c,b,c,'-')
----> 8 a/(b-c)

DivisionByZero: [<class 'decimal.DivisionByZero'>]

複利計算

10 進数10桁および3桁の有効桁数をもった計算機になったつもりで,以下の条件で預金を求める計算をおこなえ. 元本を1万円とする 利息0.3%とする 複利計算で10年でいくらになるか.

In [2]:
from decimal import *
In [15]:
digits = Decimal(10) ** -10 
getcontext().prec = 10

x = Decimal('0.1').quantize(digits)*100000
rate = Decimal('0.3').quantize(digits)/100
print(rate)
x*(1+rate)**10
0.0030000000
Out[15]:
Decimal('10304.08257')
In [9]:
digits = Decimal(10) ** -3 
getcontext().prec = 3

x = Decimal('0.1').quantize(digits)*100000
rate = Decimal('0.3').quantize(digits)/100
x*(1+rate)**10
0.003
Out[9]:
Decimal('1.00E+4')
In [ ]: