• 検索結果がありません。

π(円周率)を小数以下10,000桁まで計算 しなさい。

N/A
N/A
Protected

Academic year: 2021

シェア "π(円周率)を小数以下10,000桁まで計算 しなさい。"

Copied!
9
0
0

読み込み中.... (全文を見る)

全文

(1)

プログラミング言語 I 第 6 回 πの計算 1

埼玉大学工学部 電気電子システム工学科 伊藤 和人

Copyright ©2009 Kazuhito Ito

課題

„

π(円周率)を小数以下10,000桁まで計算 しなさい。

„

マーチンの公式を利用

⎟ ⎠

⎜ ⎞

⎝ + ⎛

⎟ ⎠

⎜ ⎞

⎝

− ⎛

⎟ ⎠

⎜ ⎞

⎝ + ⎛

⎟ ⎠

⎜ ⎞

⎝

= ⎛

110443 arctan 1 239 48

arctan 1 57 20

arctan 1 49 128

arctan 1 π 48

⎟ ⎠

⎜ ⎞

⎝

− ⎛

⎟ ⎠

⎜ ⎞

⎝

= ⎛

239 arctan 1 5 4

arctan 1 π 16

他にも、以下のような公式あり

⎟ ⎠

⎜ ⎞

⎝ + ⎛

⎟ ⎠

⎜ ⎞

⎝

− ⎛

⎟ ⎠

⎜ ⎞

⎝ + ⎛

⎟ ⎠

⎜ ⎞

⎝

= ⎛

12943 arctan 1 682 96

arctan 1 239 48

arctan 1 57 28

arctan 1 π 176

Copyright ©2009 Kazuhito Ito

πの計算

„ arctan の計算 ⇒ テイラー展開を利用

+ L

− +

−

− =

= ∞ − −

=

∑ ( 2 1 ) 1 + 3 5 7

arctan

7 5 3 1

2 1

1 x x x

x i x

x i

i i

= S

⋅ +

⋅ −

⋅ +

−

⎟ =

⎠

⎜ ⎞

⎝

⎛ 3 5 7 5 7 L

16 5 5

16 5 3

16 5 16 5 arctan 1 16

⎟ の場合

⎠

⎜ ⎞

⎝

⎛ 5 arctan 1 16

Copyright ©2009 Kazuhito Ito

テイラー展開による arctan 計算

5 16

1 =

T S = T 1

25

1 3

T = T

3 T 3

S S = − 25

3 5

T = T

5 T 5

S S = + 25

5 7

T = T

7 T 7

S

S = − T n が十分小さく なるまで繰り返す 除算、加算、減算 を実行

= S

⋅ +

⋅ −

⋅ +

−

⎟ =

⎠

⎜ ⎞

⎝

⎛ 3 5 7 5 7 L

16 5 5

16 5 3

16 5 16 5 arctan 1 16

高精度演算の考え方

„ 小数以下10,000桁 = 10 -10000 の精度

„ 細かな数値を表すための C 言語データ型

±1.175×10 -38 ~±1.175×10 +38 (32ビット、有効桁数7)

float double long double

±2.225×10 -308 ~±2.225×10 +308 (64ビット、有効桁数15)

±1.084×10 -4932 ~±1.084×10 +4932 (80ビット、有効桁数19)

long doubleを使用しても精度が不足 しかも、19桁分しか値を記憶できない

別の方法が 必要

桁数の長い数=多倍長数

„ 多数のデータ(各桁の値)をまとめて処理

„ 整数型配列の各要素が桁の値を記憶

„ 要素数を増やせば長い桁に対応可能 配列を利用

3.141592…

3 1 4 1 5 9 2 ・・・・ ..

int pi[] pi[0]

pi[1] pi[2]

pi[3] pi[4]

pi[5]

.

pi[6] pi[10000]

(2)

Copyright ©2009 Kazuhito Ito

長い桁数の演算

„ C 言語では int 型データが基本演算単位

„ 1桁の演算と2桁の演算はどちらもint型

⇒ 計算時間は同じ ( 同じ 1 回の演算処理 )

„ 1 回の int 型演算でなるべく多くの桁を計算さ せたい

„ 1つの要素がM桁を表す場合、

乗算の過程で桁数が最大で 2M 桁になる

„ int型で2M桁の整数が扱えるような桁数Mを

選択

Copyright ©2009 Kazuhito Ito

長い桁数の演算

„ int 型ではなく long 型を指定 その理由は …

„ 現在の 32 ビットプロセッサでは int 型と long 型 と同じ

⇒long型演算を最短時間(1クロック)で実行

„ もし 16 ビットプロセッサを使用したとしても、

long型=32ビットとして正しく実行できる

Copyright ©2009 Kazuhito Ito

要素の桁数の決定

„ long 型で扱える値の範囲

„ long 型の最大桁数と M の関係

„ M として 4 を選択

⇒ 1つの要素が0から9999(4桁)を表す 符号付 : -2,147,483,648 ~ 2,147,483,647 符号なし : 0 ~ 4,294,967,295(=2 32 -1)

(2 31 -1) の十進数桁数 = 9 ≧ 2M (-2 31 ~ 2 31 -1)

Copyright ©2009 Kazuhito Ito

多倍長数と配列

„ 小数点以下 10000 桁を表すには 10000/4=2500 要素の配列が必要

„ 桁と配列要素の対応 少なくとも 2 通りあり

3. 1415 9265 3589 7932 3846 … 1989 3

2 4 249

1 0 配列添え字

246

247 245 0

248 249 配列添え字

π = 方法1 方法2

方法2を採用 除算(後述)の過程で、整数部分に拡張する場合あり 方法1では拡張不可能

以下は250要素の場合

Copyright ©2009 Kazuhito Ito

多倍長加算

„ 下位桁から順に処理する void LVadd( long a[], long b[] ){

long i, c=0;

for( i=0 ; i<N ; i++ ){

a[i] += (b[i]+c);

if( a[i] >= D ){

a[i] -= D;

c = 1;

}else{

c = 0;

} } }

#define N 2500

#define D 10000 として、

加算結果がD以上 ならば桁上げ

a ← a+b

Copyright ©2009 Kazuhito Ito

多倍長減算

„ 下位桁から順に処理する void LVsub( long a[], long b[] ){

long i, c=0;

for(i=0 ; i<N ; i++ ){

a[i] -= (b[i]+c);

if( a[i] < 0 ){

a[i] += D;

c = 1;

}else{

c = 0;

} } }

減算結果が負ならば 桁借り

a ← a-b

#define N 2500

(3)

Copyright ©2009 Kazuhito Ito

多倍長精度除算

被除数(割られる数): a = a s D s + a s

−1

D s

−1

+ L + a

0

除数(割る数): b = b t D t + b t

−1

D t

−1

+ L + b

0

a<bの場合は除算は不要(q=0)なので a≧bとする すなわち

商: q = q u D u + q u

−1

D u

−1

+ L + q

0

余り: r = r t D t + r t

−1

D t

−1

+ L + r

0

r qb

a = + ( 0 ≤ r < b )

0 ,

0 ≠

≠ t

s b

a

Copyright ©2009 Kazuhito Ito

多倍長精度除算

0 1

1

D b

b D b

kb = t ′ t + t ′

−

t

−

+ L + ′

bをk倍した数 を考える

D D b

t ′ <

2 ≤

ただし k は を満たす整数

„ 計算を効率化するための工夫

a も k 倍すれば ( ) ( ) ( ) ka = q kb + kr であるから、

z商は不変

z 余りは除算後に 1/k 倍すればよい 以降では、予め被除数、除数とも k 倍し、

D D b

t <

2 ≤ が成り立つと仮定

Copyright ©2009 Kazuhito Ito

多倍長精度除算 (3)

„ 商の最上位桁位置uおよび桁値q u を求める

„ の場合

„

のとき

t

s b

a ≥

t

bD s

a ≥

−

D a D D b

s

t < <

≤ ,

2 であるから、 < 2 ⇒ < 2

t t s

s b

b a a さらに ≥ 1

t s

b

a であり、商の最上位桁は 1 に定まる よって u = s − t , q u = 1

Copyright ©2009 Kazuhito Ito

多倍長精度除算 (4)

„

の場合(続き)

„

s t

のとき

b a ≥

t

bD s

a <

−

1

1 −

−

< t

s b

a とすれば a > bD s

−

t − D s

よって u = s − t − 1 , q u = D − 2 または D − 1

j t j s t s t

s b a b a b

a = ,

−1

=

−1

, K ,

−

<

−

( j ≥ 1 )

t t

t D D

D b

b ≥ ≥ 2 より 2 b ≥ D t

+1

⇒ 2 bD s

−

t

−1

≥ D s すなわち a > bD s

−

t − D s ≥ bD s

−

t − 2 bD s

−

t

−1

= bD s

−

t

−1

( D − 2 )

( j = 1 )

多倍長精度除算(5-1)

„ の場合

„

まず、簡単化のため の場合を考える

t

s b

a <

r Qb a D

a s + s

−1

= t + とすれば ⎥

⎦

⎢ ⎥

⎣

⎢ +

≤

−

t s s

b a D

Q a

1

b Q a b R

a D Q a

t s s

0 0

1

0

⎥ , = −

⎦

⎢ ⎥

⎣

⎢ +

=

−

とおく

+ 1

= t s

Q 0 は商の候補であるが、除数を小さく見積もって いる ため、 Q 0 が実際の商 q より大きい、

すなわち ( b t D R t 0 ≤ が負になっている場合も存在する b )

商の候補を 1 増やしながら、余りが非負に

多倍長精度除算(5-2)

„ a s < b t の場合(続き)

0

0

, r R

Q

q ← ← とし、

を繰り返す b r r qb a = + , <

b Q a b R

a D Q a

t s

s

1 0 0

0

⎥ , = −

⎦

⎢ ⎥

⎣

⎢ +

=

−

とおく

≥ 0

r となるまで b

r r q

q ← − 1 , ← +

だから

− 1

>

⇒ +

< b

q a b qb a このとき

+ 1

= t

s の場合

繰り返し回数

⎟ ⎠

⎜ ⎞

⎝ ⎛ −

−

⎟ ≤

⎠

⎜ ⎞

⎝ ⎛ − + −

<

−

−1

1

−1

1

0

b

a D b

a b

a b

a D q a

Q s

t t

s s

※1

(4)

Copyright ©2009 Kazuhito Ito

多倍長精度除算 (5-3)

„ a s < b t の場合 ( 続き ) s = t + 1 の場合

すなわち※1の操作は、高々2回繰り返せば 正しい商が得られる

1

1

1

1

0 1

⎟⎟ +

⎠

⎜⎜ ⎞

⎝

= ⎛ −

⎟ ⎠

⎜ ⎞

⎝ ⎛ −

−

<

−

−

s

−−

t s t s

t b D

D b b b a b

a D b q a

Q (A)

+ 1

= t

s および b − b t D t = b t

−1

D t

−1

+ L + b

0

< D t より 3 1 1

1

1

1

⎟⎟ ⎠ + = + ≤

⎜⎜ ⎞

⎝

< ⎛

⎟⎟ +

⎠

⎜⎜ ⎞

⎝

⎛ −

−

−

t t

t t s

t s t

b D D

b D D D

b D b b b

a (B)

式(A),(B)より、繰り返し回数 Q

0

− q < 3

よって u = s − t − 1 = 0 , q

0

= Q

0

または Q

0

− 1 または Q

0

− 2

Copyright ©2009 Kazuhito Ito

多倍長精度除算 (5-4)

„ a s < b t の場合 ( 一般の場合 )

0 1

0

D , r R

Q

q ′ ← s

−

t

−

′ ← とし、

を繰り返す r

b QD r b q

a = ′ + ′ = s

−

t

−1

+ ′ b D Q a b R

a D

Q a s t

t s

s

1

0 0

1

0 −

⎥ , = −

−−

⎦

⎢ ⎥

⎣

⎢ +

= とおく

≥ 0

r ′ となるまで b

D r r D q

q ′ ← ′ − s

−

t

−1

, ′ ← ′ + s

−

t

−1

だから

1

1

1

1

+ ⇒ > −

<

−− −− −−

b D Q a b D b QD

a s t s t s t

このとき

繰り返し回数

⎟ ⎠

⎜ ⎞

⎝

⎛ −

+ −

<

−

−1 −−1

1

0

D b

a b

a D Q a

Q s t

t s s

※1

Copyright ©2009 Kazuhito Ito

多倍長精度除算 (5-5)

„ a s < b t の場合 ( 一般の場合 ) ( 続き ) 1

1

1 1

1

1

⎟ ≤ − +

⎠

⎜ ⎞

⎝

⎛ −

+ −

−

−

−

−

−

−

b D

a D

b a b

D a b

a D a

t s s t t

s t

s s

1

1

1

1

1

⎟⎟ ⎠ +

⎜⎜ ⎞

⎝

= ⎛ − +

−

=

−− −− −−

t

t t t t

s t

s t s t

t b D

D b b b D

a b

D a D

D b

a

3 1 1 = + ≤

⎟⎟ +

⎠

⎜⎜ ⎞

⎝

< ⎛

t t

t t

b D D

b D D

よって、繰り返し回数 Q

0

− Q < 3

2 1

,

1 =

0 0

−

0

−

−

−

= s t q Q Q Q

u u または または

Copyright ©2009 Kazuhito Ito

多倍長精度除算 (6)

„ 商の最上位桁位置uおよび桁値q u を求める

„ の場合

„

のとき

„

のとき

„ の場合

t

s b

a ≥

t

bD s

a ≥

−

1

, =

−

= s t q u u

t

bD s

a <

−

1 2

,

1 = − −

−

−

= s t q D D

u u または

t

s b

a <

2 1

,

1 =

0 0

−

0

−

−

−

= s t q Q Q Q

u u または または

⎥ ⎦

⎢ ⎥

⎣

⎢ +

=

−

t s s

b a D

Q

0

a

1

ただし

Copyright ©2009 Kazuhito Ito

多倍長精度除算(7)

„ 商の最上位桁位置 u および桁値 q u が得ら れたら

b D q a r = − u u a ← r として再度除算を実行

中間余り を計算

a < b になったとき、除算完了

Copyright ©2009 Kazuhito Ito

多倍長除算の例

„ D=10 として 41567÷32 を行う

0. D b D になるように被除数a、除数bをk倍する

t <

2 ≤

a=83134=8×10 4 +3×10 3 +1×10 2 +3×10+4 k=2 として

b= 64= 6×10+4 1. 83134÷64 ⇒

t

s b

a ≥ , a ≥ bD s

−

t より ,

= 83134 – 64000=19134

= 3

−

= s t

u q u = q

3

= 1

3 3

× 10

×

−

← a b q a

6 , 1 , 8 ,

4 = = =

= a s t b t

s

(5)

Copyright ©2009 Kazuhito Ito

多倍長除算の例 ( 続き 1)

2. 19134÷64 ⇒ より,

= 19134 – 12800=6334

t

s b

a < 3

6

1

19

0

=

⎥⎦ ⎥

⎢⎣ ⎢

⎥ =

⎦

⎢ ⎥

⎣

⎢ +

=

−

t s s

b a D Q a

64×3×10 2 = 19200 > 19134

64×9×10 = 5760 ≦ 6334

・・・NG

・・・OK 3. 6334÷64 ⇒

t

s b

a ≥ , a < bD s

−

t より

= 6334 – 5760=574 64×2×10 2 = 12800 ≦ 19134 ・・・OK

6 , 1 , 1 ,

4 = = =

= a s t b t

s 2 1 =

−

−

= s t

u ,

6 , 1 , 6 ,

3 = = =

= a s t b t

s

2 2

× 10

×

−

← a b q a

1 1 =

−

−

= s t

u , q u = q

1

= 9 :

1

= 9 q

:

2

= 3 q

:

2

= 2 q

1 1

× 10

×

−

← a b q a

Copyright ©2009 Kazuhito Ito

多倍長除算の例 ( 続き 2)

4. 574÷64 ⇒ より

= 574 – 512=62

t

s b

a < 9

6

1

57

0

=

⎥⎦ ⎥

⎢⎣ ⎢

⎥ =

⎦

⎢ ⎥

⎣

⎢ +

=

−

t s s

b a D Q a

64×9 = 576 > 574 ・・・NG 64×8 = 512 ≦ 574 ・・・OK

q 3 = 1, q 2 = 2, q 1 = 9, q 0 = 8 より

41567÷32 = 1298 あまり 62÷2=31 6 , 1 , 5 ,

2 = = =

= a s t b t

s

0 1 =

−

−

= s t

u ,

0 0

× 10

×

−

← a b q a

:

0

= 9 q

:

0

= 8 q

Copyright ©2009 Kazuhito Ito

多倍長除算の準備 (1)

„ 良く使う関数を準備

void LVcopy( long a[], long b[] ) { int k;

for( k=N2-1 ; k>=0 ; k-- ) b[k] = a[k];

} long GetMSD( long a[] ) { int k;

for( k=N2-1 ; k>=0 ; k-- ){

if( a[k] ) break;

} return k;

}

多倍長数aの最上位 桁位置を求める 多倍長数aを多倍長数bへコピー

上位桁から順に調べ 非ゼロならば最上位

多倍長数がゼロならば戻り値は-1

Copyright ©2009 Kazuhito Ito

整数部を考慮

„ π は整数部 (=3) あり

„ 演算の過程で、整数部分に桁上げする場 合あり

„ 整数部も統一的に扱うため、整数部まで桁 を拡張する

3. 1415 9265 3589 7932 3846 … 1989 246

247 245 0

248 249 拡張した部分

π =

N=250要素の場合 250

251

余裕をもって、配列2要素分(8桁)拡張

#define N2 (N+2)

多倍長除算の準備(2)

„ 多倍長数に単精度数を乗じる

void LVmulS( long a[], long nb, long m[] ) { int k;

long w, nCarry = 0;

long nMSDa = GetMSD(a);

for( k=0 ; k<=nMSDa ; k++ ){

w = a[k]*nb + nCarry;

m[k] = w % D;

nCarry = w/D;

} m[k] = nCarry;

for( k++ ; k<N2 ; k++ ) m[k] = 0;

aの最上位桁 位置を求める m ← a×nb

w≧Dならば桁上げ 下位からの 桁上げを加算

多倍長除算の準備(3)

„ 除数の最上位桁をD/2以上、D未満にする long Normalize( long b[], long c[] )

{ long ns, v;

long nMSD = GetMSD(b);

v = b[nMSD];

if( v == 0 ) exit(1);

ns = D/(v+1);

if( ns > 1 ) LVmulS( b, ns, c );

else LVcopy( b, c );

return ns;

}

bの最上位桁 位置を求める bを正規化しcに代入

最上位桁が0なら終了

nsはb[nMSD]をD/2以上にするために

(6)

Copyright ©2009 Kazuhito Ito

多倍長除算 (1)

long LVdiv( long a0[], long b0[], long q[] ) { long s, t, k, u, nk;

long a[N2], b[N2];

nk = Normalize( b0, b );

LVmulS( a0, nk, a );

t = GetMSD( b );

for( k=0 ; k<N2 ; k++ ) q[k] = 0;

while(1){

if( Compare( a, b ) < 0 ) break;

// a < b ならば除算終了

… } …

q ← a0/b0 bを正規化(nk倍) aもnk倍

商を0に 初期化

Copyright ©2009 Kazuhito Ito

多倍長除算 (2)

s = GetMSD( a );

if( a[s] >= b[t] ){

if( CompareOffset( a, b, s-t ) >= 0 ){

u = s-t; q[u] = 1;

}else{

u = s-t-1; q[u] = D-1;

} }else{

u = s-t-1; q[u] = (a[s]*D+a[s-1])/b[t];

}

LVmulS( b, q[u], m );

while( CompareOffset( a, m, u ) < 0 ){

q[u]--;

LVmulS( b, q[u], m );

}

商の

最上位桁位置u および値q[u]の 候補を求める

a≧m=b×q[u]を満たす 最大のq[u]を求める

t を検査

bD s

a ≥

−

Copyright ©2009 Kazuhito Ito

多倍長除算 (3)

while( 1 ){

if( Compare( a, b ) < 0 ) break;

// a < b ならば除算終了

…

LVmulS( b, q[u], m );

while( CompareOffset( a, m, u ) < 0 ){

q[u]--;

LVmulS( b, q[u], m );

} LVsubOffset( a, m, u );

} a ← a – b×q[u]*D u

a≧m=b×q[u]を満たす 最大のq[u]を求める u, q[u]の候補を求める(省略)

Copyright ©2009 Kazuhito Ito

多倍長除算の準備 (4)

int Compare( long a[], long b[] ) { int k;

long nMSDa = GetMSD(a);

long nMSDb = GetMSD(b);

if( nMSDa > nMSDb ) return 1;

if( nMSDa < nMSDb ) return -1;

for( k=nMSDa ; k>= 0 ; k-- ){

if( a[k] > b[k] ) return 1;

if( a[k] < b[k] ) return -1;

} return 0;

}

戻り値 a=b ⇒ 0 a>b ⇒ 1 a<b ⇒ -1

最上位桁が 同じ場合

„ 多倍長数 a と b を比較

すべて等しい ⇒ a=b

aの最上位桁が bの最上位桁より 上なら a>b

Copyright ©2009 Kazuhito Ito

多倍長除算の準備(5)

int CompareOffset( long a[], long b[], long No ) { int k;

long nMSDa = GetMSD(a);

long nMSDb = GetMSD(b)+No;

if( nMSDa > nMSDb ) return 1;

if( nMSDa < nMSDb ) return -1;

for( k=nMSDa ; k>=No ; k-- ){

if( a[k] > b[k-No] ) return 1;

if( a[k] < b[k-No] ) return -1;

} for( ; k>=0 ; k-- ) if( a[k] ) return 1;

return 0;

}

„ 多倍長数aとbを桁をずらして比較

a[No-1]から a[0]の中に 非ゼロのもの があれば aの方が大きい

ここに来たとき

a[nMSDa],...,a[No]

と

b[nMSDa-No],...,b[0]

が一致

Copyright ©2009 Kazuhito Ito

多倍長除算の準備(6-1)

void LVsubOffset( long a[], long b[], long No ) { int k;

long v = 0;

long nMSDb = GetMSD(b);

for( k=0 ; k<=nMSDb ; k++ ){

if( a[k+No] >= b[k]+v ){

a[k+No] –= (b[k]+v); v = 0;

}else{

a[k+No] += D;

a[k+No] –= (b[k]+v); v = 1;

} }

a ← a – b×D No

桁借りが ある場合

„ 多倍長数aからbを桁をずらして引き算

最上位桁 までbを引く

次のスライドへ続く

(7)

Copyright ©2009 Kazuhito Ito

多倍長除算の準備 (6-2)

void LVsubOffset( long a[], long b[], long No ) { …

for( ; v ; k++ ){

if( a[k+No] ){

a[k+No]--; v = 0;

}else{

a[k+No] = D-1; v = 1;

} } }

上位桁への桁借りを 処理

„ 多倍長数 a と b を比較

前のスライドから続き

Copyright ©2009 Kazuhito Ito

被除数と除数の桁あわせ (1)

„ 多倍長数が表す数

0 N-2

N-1

A ’ =

N N+1

(D=10000)

∑ +

=

= 1

0

D ] [ a ' N

k

k k

A 配列添え字

やはり整数 多倍長除算結果(商) ∑ +

=

=

= 1

0

D ] [ ' q

' ' N

k

k k

B Q A

多倍長除算は、多倍長数aが整数値を表すと想定 多倍長数a

1 2345 6789 … 9012 要素の値

整数値

6789 2345 1

0 9012

小数点 位置

Copyright ©2009 Kazuhito Ito

被除数と除数の桁あわせ (2)

„ 多倍長数による小数の表現 (D=10000)

N N k

N

k A D

k

A −

+

=

− =

= ∑ 1 a [ ] D '

0

(多倍長数aが表す整数値 A’ と実際値 A の関係) 小数点位置を移動

0 N-2

N-1

A =

N N+1 配列添え字

1.2345 6789 … 9012 要素の値

実際値

6789 2345 1

0 9012

Copyright ©2009 Kazuhito Ito

被除数と除数の桁あわせ (3)

„ 多倍長数による小数の除算 被除数 A を除数 B で除算 ⇒

' ' D '

D '

B A B

A B A

N N =

=

= − −

商

必要な商は N N

N

k

N k

BD D A

B k A

Q = + = − =

=

∑ 1 − 0

D ] [ q つまり

小数どうしの除算は実際値 A ( B )を 整数値 A ’( B ’)とみなして多倍長除算を行う ただし、

商は整数値形式で得られる ∑ +

=

=

= 1

0

D ] [ ' q ' N

k

k k

B A B A

除数はD N 倍して除算を行えばよい

除算の実行

long q[N2], r[N2];

long a[N2] = {0}, b[N2] = {0};

a[N] = 16;

b[0] = 5;

LVdiv( a, b, q, r ); // q = 16/5

„ 16/5を実行

16×D N-N =16 5×D 0-N = 5×D -N

0 N-2

N-1 N N+1 添え字

a 0 16 0 0 0

b 0 0 0 0 5

q 0 3 2 0 0

A =16 Q =3.2 B ’=5

πの計算 (1)

void CalcPi( void )

{ long s[N+2], s5[N+2], s239[N+2];

long t[N+2] = {0}, q[N2], r[N2];

long d2[N+2] = {0}, d[N+2] = {0};

int pm;

/* 16*arctan(1/5) を計算 */

t[N] = 16;

d2[0] = 5;

LVdiv( t, d2, s5, r ); // s5 = 16/5 LVcopy( s5, t ); // t = 16/5

…

⎟ ⎠

⎜ ⎞

⎝

⎛ 5 arctan 1

16 を求める

(8)

Copyright ©2009 Kazuhito Ito

πの計算 (2)

d2[0] = 25;

d[0] = 3;

pm = 0; // 減算 while(1){

LVdiv( t, d2, t, r ); // t = t/25 if( GetMSD(t) < 0 ) break;

LVdiv( t, d, s, r ); // s = t/d if( pm ){ // 加算

LVadd( s5, s ); pm = 0;

}else{ // 減算

LVsub( s5, s ); pm = 1;

} LVaddS( d, 2 );

}

tが0に なれば 終了 ここでは t=16/5

s5 ← s5 + s s5 ← s5 - s d ← d+2

Copyright ©2009 Kazuhito Ito

πの計算 (3)

… /* 4*arctan(1/239) を計算 */

t[N] = 4;

d2[0] = 239;

LVdiv( t, d2, s239, r ); // s239 = 4/239 LVcopy( s239, t ); // t = 4/239

…

⎟ ⎠

⎜ ⎞

⎝

⎛ 239 arctan 1

4 を求める

Copyright ©2009 Kazuhito Ito

πの計算 (4)

d2[1] = 5; d2[0] = 7121; // 239*239 d[2] = 0; d[1] = 0; d[0] = 3;

pm = 0; // 減算 while(1){

LVdiv( t, d2, t, r ); // t = t/(239*239) if( GetMSD(t) < 0 ) break;

LVdiv( t, d, s, r ); // s = t/d if( pm ){ // 加算

LVadd( s239, s ); pm = 0;

}else{ // 減算

LVsub( s239, s ); pm = 1;

} LVaddS( d, 2 );

}

tが0になれば 終了

ここでは t=4/239

s239 += s s239 -= s d ← d+2

Copyright ©2009 Kazuhito Ito

πの計算 (5)

void CalcPi( void )

{ /* 16*arctan(1/5) を計算 */

… /* 4*arctan(1/239) を計算 */

…

LVsub( s5, s239 );

} s5-s239 = π

Copyright ©2009 Kazuhito Ito

実行結果

3.

1415926535 8979323846 2643383279 5028841971 6939937510 5820974944 5923078164 0628620899 8628034825 3421170679

…

2162484391 4035998953 5394590944 0704691209 1409387001 2645600162 3742880210 9276457931 0657922955 2498872758 4610126483 6999892256 9596881592 0560010165 5256375662

正しくは78 N=2500 ⇒ 小数点以下10000桁まで計算

正しく求めるには、N=2501 とする

3.

1415926535 8979323846 2643383279 5028841971 6939937510

…

4610126483 6999892256 9596881592 0560010165 5256375678 5646

Copyright ©2009 Kazuhito Ito

プログラムの実行時間

„ 桁数Nとプログラム実行時間の関係

0.01 0.10 1.00 10.00 100.00 1000.00

100 1000 10000

N

秒

O(n 3 )

PentiumIV

2.4GHz

Celeron M

1.5GHz

(9)

Copyright ©2009 Kazuhito Ito

まとめ

„ πの計算

„ 整数型の配列を利用して多倍長数を演算

„ 改善の余地あり

参照

関連したドキュメント

l 「指定したスキャン速度以下でデータを要求」 : このモード では、 最大スキャン速度として設定されている値を指 定します。 有効な範囲は 10 から 99999990

WAV/AIFF ファイルから BR シリーズのデータへの変換(Import)において、サンプリング周波 数が 44.1kHz 以外の WAV ファイルが選択されました。.

⑥ニューマチックケーソン 職種 設計計画 設計計算 設計図 数量計算 照査 報告書作成 合計.. 設計計画 設計計算 設計図 数量計算

国の5カ年計画である「第11次交通安全基本計画」の目標値は、令和7年までに死者数を2千人以下、重傷者数を2万2千人

製造業その他の業界 「資本金3億円を超える」 かつ 「従業員数300人を超える」 「資本金3億円以下」 または 「従業員300人以下」

ある周波数帯域を時間軸方向で複数に分割し,各時分割された周波数帯域をタイムスロット

項   目  単 位  桁   数  底辺及び垂線長 m 小数点以下3桁 境界辺長 m  小数点以下3桁

、肩 かた 深 ふかさ を掛け合わせて、ある定数で 割り、積石数を算出する近似計算法が 使われるようになりました。この定数は船