by konisi » 2006年6月24日(土) 20:57
QWord型とInt64型用の、掛け算と割り算と余り算(Mod)を作りました。
関数のソースコード
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
Function Mul_ForQWord(A As QWord,B As QWord) As QWord
Dim i As Long
Dim Ret As QWord
If B=0 then
Mul_ForQWord=0
Exit Function
End If
If (B And 1)=1 then Ret=A else Ret=0
For i=0 To 62
B=B>>1
A=A<<1
If B=0 then Exit For
If (B And 1)=1 then Ret=Ret+A
Next i
Mul_ForQWord=Ret
End Function
Function Mul_ForInt64(A As Int64,B As Int64) As Int64
Dim FlagA As Long,FlagB As Long
Dim C As Int64
If A<0 then FlagA=1:A=0-A
If B<0 then FlagB=1:B=0-B
C=Mul_ForQWord(A As QWord,B As QWord)
If FlagA=1 then C=0-C
If FlagB=1 then C=0-C
Mul_ForInt64=C
End Function
Function Div_ForQWord(A As QWord,B As QWord) As QWord
'Ret=A/B
Dim i As Long,C As QWord,Ret As QWord
If A<B then
Div_ForQWord=0
Exit Function
ElseIf A=B then
Div_ForQWord=1
Exit Function
ElseIf B=0 then
'0除算は出来ません。
Div_ForQWord=&HFFFFFFFFFFFFFFFF
debug
Exit Function
End If
C=A
i=0
Do
i+=1
A=A>>1
If A<=B then Exit Do
Loop
If A=B then
Div_ForQWord=1<<i
Exit Function
End If
i-=1
C=C-(B<<i)
Ret=1<<i
While TRUE
i-=1
A=C>>i
If A>=B then
Ret=Ret+(1<<i)
C=C-(B<<i)
End If
If C=0 then
Exit While
End If
If i=0 then Exit While
Wend
Div_ForQWord=Ret
End Function
Function Div_ForInt64(A As Int64,B As Int64) As Int64
Dim FlagA As Long,FlagB As Long
Dim C As Int64
If A<0 then FlagA=1:A=0-A
If B<0 then FlagB=1:B=0-B
C=Div_ForQWord(A As QWord,B As QWord)
If FlagA=1 then C=0-C
If FlagB=1 then C=0-C
Div_ForInt64=C
End Function
Function Mod_ForQWord(A As QWord,B As QWord) As QWord
Mod_ForQWord=A-Mul_ForQWord(Div_ForQWord(A,B),B)
End Function
Function Mod_ForInt64(A As Int64,B As Int64) As Int64
Mod_ForInt64=A-Mul_ForInt64(Div_ForInt64(A,B),B)
End Function
各関数の説明
ここをクリックすると各関数の説明が表示されます。 [ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]
Mul_ForQWord(A As QWord,B As QWord) As QWord
第一引数:掛けられる数を指定します。
第二引数:掛ける数を指定します。
返り値:掛け算の結果が返ります。
備考:この関数では符号無し掛け算を行います。
Mul_ForInt64(A As Int64,B As Int64) As Int64
第一引数:掛けられる数を指定します。
第二引数:掛ける数を指定します。
返り値:掛け算の結果が返ります。
備考:この関数では符号有り掛け算を行います。ただし、少し手を抜いているので符号無し版を同時に定義しなければ使えません。
Div_ForQWord(A As QWord,B As QWord) As QWord
第一引数:割られる数を指定します。
第二引数:割る数を指定します。
返り値:割り算の結果が返ります。
備考:この関数では符号無し割り算を行います。
Div_ForInt64(A As Int64,B As Int64) As Int64
第一引数:割られる数を指定します。
第二引数:割る数を指定します。
返り値:割り算の結果が返ります。
備考:この関数では符号有り割り算を行います。ただし、少し手を抜いているので符号無し版を同時に定義しなければ使えません。
Mod_ForQWord(A As QWord,B As QWord) As QWord
第一引数:割られる数を指定します。
第二引数:割る数を指定します。
返り値:割り算の余りを返します。
備考:この関数では符号無し割り算を行います。
Mod_ForInt64(A As Int64,B As Int64) As Int64
第一引数:割られる数を指定します。
第二引数:割る数を指定します。
返り値:割り算の余りを返します。
備考:この関数では符号有り割り算を行います。
64ビット型の乗除算は、内部でDouble型に直してから行うらしく大きい数を行うとずれが生じます。
これらの関数ではシフト演算と加算減算のみの作業でこれらを行っているため、ずれは生じません。(ただし、普通に乗除算を行うより少し遅くなります。)
QWord型とInt64型用の、掛け算と割り算と余り算(Mod)を作りました。
関数のソースコード
[hide][code]Function Mul_ForQWord(A As QWord,B As QWord) As QWord
Dim i As Long
Dim Ret As QWord
If B=0 then
Mul_ForQWord=0
Exit Function
End If
If (B And 1)=1 then Ret=A else Ret=0
For i=0 To 62
B=B>>1
A=A<<1
If B=0 then Exit For
If (B And 1)=1 then Ret=Ret+A
Next i
Mul_ForQWord=Ret
End Function
Function Mul_ForInt64(A As Int64,B As Int64) As Int64
Dim FlagA As Long,FlagB As Long
Dim C As Int64
If A<0 then FlagA=1:A=0-A
If B<0 then FlagB=1:B=0-B
C=Mul_ForQWord(A As QWord,B As QWord)
If FlagA=1 then C=0-C
If FlagB=1 then C=0-C
Mul_ForInt64=C
End Function
Function Div_ForQWord(A As QWord,B As QWord) As QWord
'Ret=A/B
Dim i As Long,C As QWord,Ret As QWord
If A<B then
Div_ForQWord=0
Exit Function
ElseIf A=B then
Div_ForQWord=1
Exit Function
ElseIf B=0 then
'0除算は出来ません。
Div_ForQWord=&HFFFFFFFFFFFFFFFF
debug
Exit Function
End If
C=A
i=0
Do
i+=1
A=A>>1
If A<=B then Exit Do
Loop
If A=B then
Div_ForQWord=1<<i
Exit Function
End If
i-=1
C=C-(B<<i)
Ret=1<<i
While TRUE
i-=1
A=C>>i
If A>=B then
Ret=Ret+(1<<i)
C=C-(B<<i)
End If
If C=0 then
Exit While
End If
If i=0 then Exit While
Wend
Div_ForQWord=Ret
End Function
Function Div_ForInt64(A As Int64,B As Int64) As Int64
Dim FlagA As Long,FlagB As Long
Dim C As Int64
If A<0 then FlagA=1:A=0-A
If B<0 then FlagB=1:B=0-B
C=Div_ForQWord(A As QWord,B As QWord)
If FlagA=1 then C=0-C
If FlagB=1 then C=0-C
Div_ForInt64=C
End Function
Function Mod_ForQWord(A As QWord,B As QWord) As QWord
Mod_ForQWord=A-Mul_ForQWord(Div_ForQWord(A,B),B)
End Function
Function Mod_ForInt64(A As Int64,B As Int64) As Int64
Mod_ForInt64=A-Mul_ForInt64(Div_ForInt64(A,B),B)
End Function
[/code][/hide]
各関数の説明
[hide=ここをクリックすると各関数の説明が表示されます。]
Mul_ForQWord(A As QWord,B As QWord) As QWord
第一引数:掛けられる数を指定します。
第二引数:掛ける数を指定します。
返り値:掛け算の結果が返ります。
備考:この関数では符号無し掛け算を行います。
Mul_ForInt64(A As Int64,B As Int64) As Int64
第一引数:掛けられる数を指定します。
第二引数:掛ける数を指定します。
返り値:掛け算の結果が返ります。
備考:この関数では符号有り掛け算を行います。ただし、少し手を抜いているので符号無し版を同時に定義しなければ使えません。
Div_ForQWord(A As QWord,B As QWord) As QWord
第一引数:割られる数を指定します。
第二引数:割る数を指定します。
返り値:割り算の結果が返ります。
備考:この関数では符号無し割り算を行います。
Div_ForInt64(A As Int64,B As Int64) As Int64
第一引数:割られる数を指定します。
第二引数:割る数を指定します。
返り値:割り算の結果が返ります。
備考:この関数では符号有り割り算を行います。ただし、少し手を抜いているので符号無し版を同時に定義しなければ使えません。
Mod_ForQWord(A As QWord,B As QWord) As QWord
第一引数:割られる数を指定します。
第二引数:割る数を指定します。
返り値:割り算の余りを返します。
備考:この関数では符号無し割り算を行います。
Mod_ForInt64(A As Int64,B As Int64) As Int64
第一引数:割られる数を指定します。
第二引数:割る数を指定します。
返り値:割り算の余りを返します。
備考:この関数では符号有り割り算を行います。
[/hide]
64ビット型の乗除算は、内部でDouble型に直してから行うらしく大きい数を行うとずれが生じます。
これらの関数ではシフト演算と加算減算のみの作業でこれらを行っているため、ずれは生じません。(ただし、普通に乗除算を行うより少し遅くなります。)