四則演算方式 |
乗算 |
最終更新日:2007/04/26 新規 |
●概要
配列 * 配列、配列 * Base の二通りの乗算がある。配列 * Base
の乗算は速い。演算は絶対値で行い、符号は別途調整される。指数部は加算で求められる。
●方法
A * B → C において、
○前処理
- 少なくとも一方がZero のときは、Zero。
- 同符号のときは、Positive、異符号のときはNegative。
- 少なくとも一方が、10n であれば、指数調整のみ。
- 仮の指数は、双方の指数の和。
- 双方の数値がBase 未満かどうかを検査。以下に続く。
○仮数部乗算
仮数部は、0.1・・・から 0.9・・・・ なので、乗算結果は、絶対に 1
未満となる。従って、仮数部乗算結果は先頭に小数点があるとする。また、結果の配列数は、両者の和となる。
○Base * Base
以下のように、ネイティブ乗算で行う。CNum() が結果の配列
Dim R As Long = CLng(A.Mant(0)) * CLng(B.Mant(0))
ReDim CNum(1)
CNum(1) = R Mod Base
CNum(0) = R \ Base
例えば、0.95 * 0.87 = 0.8265 の仮数部乗算は、
95000000 * 87000000 = 82650000|00000000 これは、0.8265 である。
○配列 * Base
どちらかが、Base未満のとき。以下のように行う。
B が、Base 未満
Dim i As Integer
Dim PC, CU As Long
Dim cc As Integer = A.Length
ReDim C(cc)
'結果配列数は +1
CU = 0
For i = cc - 1 To 0 Step -1 '後ろから
PC = A(i) * CLng(B) + CU
C(i + 1) = CInt(PC Mod Base) '規格化された積
CU = CInt(PC \ Base)
'キャリー
Next
C(0) = CU '最後のキャリー
○配列 * 配列
配列同士では、以前の結果に部分積を規格化しながら足し込んで行く以下のような処理となる。
Dim i, j, ix As Integer
Dim R, CU As Long
Dim ac As Integer = A.Length
Dim bc As Integer = B.Length
Dim cc As Integer = ac + bc - 1
ReDim C(cc)
'結果配列を初期化
For i = bc - 1 To 0 Step -1
If B(i) > 0 Then
'B>0 のとだけ乗算
CU = 0
For j = ac - 1 To 0 Step -1
ix = i + j + 1
'部分積の格納場所(双方の要素番号の和)
R = CLng(A(j)) * CLng(B(i)) +
CU + C(ix) '以前の結果にその時の部分積を加算
C(ix) = R Mod Base
CU = R \ Base
Next
C(ix - 1) = CU
'その行最後のキャリー(最初なので格納のみ)
End If
Next
|
|
a0 |
a1 |
a2 |
|
|
|
b0 |
b1 |
|
|
a0・b1 |
a1・b1 |
a2・b1 |
|
a0・b0 |
a1・b0 |
a2・b0 |
|
c0 |
c1 |
c2 |
c3 |
c4 |
上図で、a1・b0 などは、Long値の規格化前の部分積で、規格化とは、例えば、
c2 の新しい値 = (c2 + a1・bo + CU) Mod Base
次へのキャリー = (c2 + a1・bo + CU) \ Base
を行うことである。
○正規化
上記、いずれの乗算結果も、先頭に小数点があるので、同じ正規化で良い。先頭の配列の頭出しを行う。左にシフトした桁数だけ、指数調整(-)する。末尾の 0
要素を除去する。有効桁数を数える。
|