| 
上へ整数 → MegaLong
 実数 → MegaLong
 10進数 → MegaLong
 文字列 → MegaLong
 整数部分
 小数部分
 部分値
 MegaLong → Long
 MegaLong → Double
 文字列変換
 |  | 
  
    | 数値変換 |  
    | 整数 → MegaLong  |  
    | 最終更新日:2007/02/20 改訂 |  ●概要  整数とは、Byte、SByte、Short、UShort、Integer、UInteger、Long、ULong を言う。 ●方針  整数は絶対値の大きさによって処理が異なる。 
  基数の2乗(1億X1億) 未満であれば、Long またはULong 
  にて、直接処理を行う。この処理では、事前正規化を行い、高速化が図られている。Byte、SByte、Short、UShort、Integer、UInteger 
  の場合は、無条件でこの処理となる。基数の2乗(1億X1億) 以上の場合は、1億進数の仮数部配列に変換(基数変換)し、正規化を行う。Long、ULong 
  の場合に、この処理になる可能性がある。以前は、Decimal で行っていたが、遅いのでこの方式に変更した。 ●方法 ○Base*Base 未満の処理  Me は、返す対象となるインスタンス 
	0 はZero とする。符号を決定。絶対値 V(Long) とする。p = GetDecPower(V) で、10進指数を求める。(関数は下記)
 10p ≦ V < 10p+1 → 指数は p とする
 
e = p Mod 8 は、8桁区切りにしたときの端数。n = (p \ 8) + 1 は、とりあえず必要な配列サイズ
p の値に従って以下の変換を行う。
 NormT() As Integer = {10000000, 1000000, 
	100000, 10000, 1000, 100, 10, 1}
 
 V = V * NormT(e)           
	'正規化を前もって行うための係数
 Dim CU As Long = V
 For i = n - 1 To 0 Step -1
 Me.Mant(i) = CU Mod Base
 CU = CU \ Base
 Next
 
指数は、p +1 となる。後ろの不要な 0 を除去して終了。 
	→正規化を前もって行う とは、数値の10進桁数を 8 の倍数にしておくことを言う。例えば、
 12345 → 12345000 1000倍する、 123456789 → 1234567890000000 1千万倍する。
 
 など。
 
	 整数の10進指数を求める関数。従来、Fix(Log10(V)) としていたが、これだと、Double の精度の問題で、9999999999999999 
	は、1*1016 となり、指数が16 となってしまい不都合であった。以下のように、10進テーブルをバイナリサーチする。 
	Friend Function GetDecPower(ByVal V As Long) 
	As IntegerDim p As Integer = Array.BinarySearch(DecPow, 
	V)
 'DecPow 1,10,100,1000,・・・・なるテーブル
 Select Case p
 Case -1
 Return -1
 Case Is >= 0
 Return p                             
    '一致(殆どありえないが)
 Case Else
 Return (-1 
	Xor p) - 1            
	'不一致の場合、BinarySearch の仕様による
 End Select
 End Function
 ○Base*Base 以上の処理  この値では、事前正規化ができないので、仮数部配列の正規化処理が伴う。 ・特別処理:Long で、Long.MinValue の場合は、符号反転するとOverflow するので、定数として持っているMegaLong を返す。 以下の処理となる。ULong の場合もほぼ同じ(符号処理が不要、演算はULong が異なる)。 Dim sgn As MegaSign = MegaSign.PositiveDim Q, R As Long
 ReDim Me.Mant(2)               
'値範囲が分っているので配列サイズは 3 となる
 If V < 0 Then
 V = -V
 sgn = MegaSign.Negative
 End If
 Q = V
 R = Base
 For i As Integer = 2 To 0 Step -1
 Me.Mant(i) = Q Mod R
 Q = Q \ R
 Next
 NormalizeMe()               
'正規化(以下の関数)
 Me.Sign = sgn
 Private Sub NormalizeMe()Dim Ix, p, e, Z As Integer
 p = Me.Mant.Length
 Ix = GetTopDigit(Me.Mant(0))     '先頭要素の先頭桁位置
 e = (p - 1) * 8 + 8 - Ix
 Me.Exp = e
 NumUp(Me.Mant, Ix)        '仮数部全体を、Ix 分シフトアップ
 RemoveEndZeroElement(Me.Mant)   '末尾の 0 要素を除去
 Z = Me.Mant.Length
 Ix = GetLastDigit(Me.Mant(Z - 1))  '末尾桁数を検査
 Me.Length = (Z - 1) * 8 + Ix + 1
 End Sub
 
 |