作成者 |
メッセージ |
|
|
Val関数にて、文字列中の「0」の部分が戻り値では「1」となるバグがあります。
隠し関数が原因のようなので、以下のように修正してみました。
コード:
Function Kakeru_QWord(A As Byte,B As QWord) As QWord
Dim C As QWord
Dim I As Long
C = 0
If A>0 then 'この行と
For I=1 To A
C = C + B
Next I
Else
C = 0 'この行を修正
End If
Kakeru_QWord = C
End Function
Function Kakeru_Int64(A As Byte,B As Int64) As Int64
Dim C As QWord
Dim I As Long
C = 0
If A>0 then '同じくこの行と
For I=1 To A
C = C + B
Next I
Else
C = 0 'この行を修正
End If
Kakeru_Int64 = C
End Function
Val関数にて、文字列中の「0」の部分が戻り値では「1」となるバグがあります。 隠し関数が原因のようなので、以下のように修正してみました。
[code] Function Kakeru_QWord(A As Byte,B As QWord) As QWord Dim C As QWord Dim I As Long C = 0 If A>0 then 'この行と For I=1 To A C = C + B Next I Else C = 0 'この行を修正 End If Kakeru_QWord = C End Function
Function Kakeru_Int64(A As Byte,B As Int64) As Int64 Dim C As QWord Dim I As Long C = 0 If A>0 then '同じくこの行と For I=1 To A C = C + B Next I Else C = 0 'この行を修正 End If Kakeru_Int64 = C End Function [/code]
|
|
|
投稿記事 |
Posted: 2007年3月05日(月) 03:55 |
|
|
|
|
|
>>tak
> 除算では条件を満たすまで無限ループ(!)を行っていますが
最高でも63回程度のはずです。(毎回iの数値を減算していって、i=0の時に抜け出すため。)
> こちらでは確認できませんでした。といっても QWord * QWord の組み合わせしか検証していませんが(汗
調べたところ、乗算の場合はQWord型のまま行うみたいなのですが、除算の場合にDouble型を使用しているようです。
> 効率は良くなさそうとのことですが、乗算関数同様に最適化されているように見えます。
比較したいところでしたが、手元にあるOpcodes.hlp(機械語の速度の表みたいなやつ)に載っていない命令がいくつもあったので比較できません。
誰か次の物についてクロック数が分かる人は教えてください。
FILD,FDIVRP,FSTP,FLD,FNSTCW,OpdSz,FLDCW,FISTP,FLDCW
実数除算のほうにクロック数が分からない未知の命令語がこれだけあります。
お手上げですね^^;
分かる部分だけで38クロックです。
整数除算の方は分かるやつばっかりなのですぐに算出できました。
途中で後分岐のループが一個入ってますが、それをスルーしたとして166クロック~228クロック、ループを一回繰り返すごとに+16クロックです。
ちなみにこのループを使わない場合もあって、そちらは158クロックでした。
ところで、QWord型に対してインクリメントを行った時に変数の値が壊れたような気がしました。誰か試してみてください。
>>tak > 除算では条件を満たすまで無限ループ(!)を行っていますが 最高でも63回程度のはずです。(毎回iの数値を減算していって、i=0の時に抜け出すため。)
> こちらでは確認できませんでした。といっても QWord * QWord の組み合わせしか検証していませんが(汗 調べたところ、乗算の場合はQWord型のまま行うみたいなのですが、除算の場合にDouble型を使用しているようです。
> 効率は良くなさそうとのことですが、乗算関数同様に最適化されているように見えます。 比較したいところでしたが、手元にあるOpcodes.hlp(機械語の速度の表みたいなやつ)に載っていない命令がいくつもあったので比較できません。 誰か次の物についてクロック数が分かる人は教えてください。 FILD,FDIVRP,FSTP,FLD,FNSTCW,OpdSz,FLDCW,FISTP,FLDCW 実数除算のほうにクロック数が分からない未知の命令語がこれだけあります。 お手上げですね^^; 分かる部分だけで38クロックです。
整数除算の方は分かるやつばっかりなのですぐに算出できました。 途中で後分岐のループが一個入ってますが、それをスルーしたとして166クロック~228クロック、ループを一回繰り返すごとに+16クロックです。 ちなみにこのループを使わない場合もあって、そちらは158クロックでした。
ところで、QWord型に対してインクリメントを行った時に変数の値が壊れたような気がしました。誰か試してみてください。
|
|
|
投稿記事 |
Posted: 2006年6月25日(日) 19:08 |
|
|
|
|
|
自分はいったい何をしているのだろう?という疑問に駆られたので、コーディング作業を中断して覗いてみましたよ、EXE の中を。
そしたら地雷原や不審な挙動の原因が少しだけ判りました。それは後ほどバグ板に提出する方向で。
ここでは調査結果の一部を報告します。
> 64ビット型の乗除算は、内部でDouble型に直してから行うらしく
こちらでは確認できませんでした。といっても QWord * QWord の組み合わせしか検証していませんが(汗
この現象が発生する条件を記してもらえればたすかります(バグ板で)。
なお QWord の乗算では、洗練された専用乗算ルーチンを使用して計算していました。
> ところで整数除算演算子 \ を使ったときだけは64ビット整数でも浮動小数点演算を使っていないようです。
> 効率はあまり良くなさそうですが。
こちらは確認できました。こちらも専用の関数を呼び出していますね。
効率は良くなさそうとのことですが、乗算関数同様に最適化されているように見えます。おそらく C++ が吐いたコードでしょうね。
自分はいったい何をしているのだろう?という疑問に駆られたので、コーディング作業を中断して覗いてみましたよ、EXE の中を。 そしたら地雷原や不審な挙動の原因が少しだけ判りました。それは後ほどバグ板に提出する方向で。 ここでは調査結果の一部を報告します。
> 64ビット型の乗除算は、内部でDouble型に直してから行うらしく こちらでは確認できませんでした。といっても QWord * QWord の組み合わせしか検証していませんが(汗 この現象が発生する条件を記してもらえればたすかります(バグ板で)。 なお QWord の乗算では、洗練された専用乗算ルーチンを使用して計算していました。
> ところで整数除算演算子 \ を使ったときだけは64ビット整数でも浮動小数点演算を使っていないようです。 > 効率はあまり良くなさそうですが。 こちらは確認できました。こちらも専用の関数を呼び出していますね。 効率は良くなさそうとのことですが、乗算関数同様に最適化されているように見えます。おそらく C++ が吐いたコードでしょうね。
|
|
|
投稿記事 |
Posted: 2006年6月25日(日) 12:21 |
|
|
|
|
|
既に書いた分だけでもバグ報告へ出したほうがよいと思います。
ところで整数除算演算子 \ を使ったときだけは64ビット整数でも浮動小数点演算を使っていないようです。
効率はあまり良くなさそうですが。
既に書いた分だけでもバグ報告へ出したほうがよいと思います。
ところで整数除算演算子 \ を使ったときだけは64ビット整数でも浮動小数点演算を使っていないようです。 効率はあまり良くなさそうですが。
|
|
|
投稿記事 |
Posted: 2006年6月25日(日) 09:25 |
|
|
|
|
|
64bit 版乗除算について
このアルゴリズムでは、乗算は 63 回、除算では条件を満たすまで無限ループ(!)を行っていますが、実際は乗算ならば 4 回の乗算と 3 回の加算、また除算ならば2 回の除算と 1 回の加算、その他細々としたビット演算で計算可能です。
と言うわけで作ってみたのですが、AB が期待したとおりに動作しなかったり、地雷を踏みまくったりでそれらを回避するために酷いコードになったので、ここに挙げるのは遠慮させてもらいます(ぉ
バグ報告レポートを作成していたのですが、結構な数になったのでくじけちまったorz
64bit 版乗除算について このアルゴリズムでは、乗算は 63 回、除算では条件を満たすまで無限ループ(!)を行っていますが、実際は乗算ならば 4 回の乗算と 3 回の加算、また除算ならば2 回の除算と 1 回の加算、その他細々としたビット演算で計算可能です。 と言うわけで作ってみたのですが、AB が期待したとおりに動作しなかったり、地雷を踏みまくったりでそれらを回避するために酷いコードになったので、ここに挙げるのは遠慮させてもらいます(ぉ バグ報告レポートを作成していたのですが、結構な数になったのでくじけちまったorz
|
|
|
投稿記事 |
Posted: 2006年6月25日(日) 02:46 |
|
|
|
|
|
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型に直してから行うらしく大きい数を行うとずれが生じます。 これらの関数ではシフト演算と加算減算のみの作業でこれらを行っているため、ずれは生じません。(ただし、普通に乗除算を行うより少し遅くなります。)
|
|
|
投稿記事 |
Posted: 2006年6月24日(土) 20:57 |
|
|
|
|
|
関数のソースコード
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: Function StrForQWord$(qwd As QWord) As String
Dim buffer[32] As Byte
Dim i As Long
Dim a As QWord
Dim s=48 As Byte
Dim buffer2[32] As Byte
Dim I As Long
Dim x As QWord
Dim y As QWord
i = 0
x = 10
y = 1
debug
Do
a = qwd Mod x
buffer = Waru_QWord(a,y) + s As Byte
qwd = qwd - a
x = x * 10
y = y * 10
i = i + 1
Loop Until qwd = 0
buffer2 = 0
For I=1 To i
buffer2(I-1)=buffer(i-I)
Next I
StrForQWord$ = MakeStr(buffer2)
End Function
Function Waru_QWord(A As QWord,B As QWord) As Byte
Dim C As QWord
Dim I As Byte
Do
C=A
A=A-B
If A>C then Exit Do
I=I+1
Loop
Waru_QWord=I
End Function
Function ValForQWordString(A$ As String) As QWord
ValForQWordString=ValForQWord(StrPtr(A$))
End Function
Function ValForQWord(pA As BytePtr) As QWord
Dim I As Long
Dim buffer(32) As Byte
Dim A$ As String
Dim x As QWord
A$=MakeStr(pA)
For I=0 To Len(A$)-1
buffer(I)=A$(I)-48
Next I
x=1
For I=Len(A$)-1 To 0 Step -1
If buffer(I)>10 then Exit For
ValForQWord = ValForQWord + Kakeru_QWord(buffer(I),x)
x = x * 10
Next I
End Function
Function Kakeru_QWord(A As Byte,B As QWord) As QWord
Dim C As QWord
Dim I As Long
C = 0
If A>1 then
For I=1 To A
C = C + B
Next I
Else
C = B
End If
Kakeru_QWord = C
End Function
Sub InputForQWord(PrintString As String,fQuestion As Long,ByRef Inp As QWord)
Dim A$ As String
If fQuestion then
Print PrintString+"?";
Else
Print PrintString;
End If
Input A$
Inp=ValForQWordString(A$)
End Sub
Sub PrintForQWord(PrintQWord As QWord,fReturn As Long)
Dim A$ As String
A$=StrForQWord$(PrintQWord)
If fReturn then
Print A$
Else
Print A$;
End If
End Sub
Function StrForInt64$(it64 As Int64) As String
Dim buffer[32] As Byte
Dim i As Long
Dim a As QWord
Dim s=48 As Byte
Dim buffer2[32] As Byte
Dim I As Long
Dim x As QWord
Dim y As QWord
Dim flag=0 As Long
If it64<0 then
flag=1
it64 = -1 * it64
End If
i = 0
x = 10
y = 1
Do
a = it64 Mod x
buffer = Waru_Int64(a,y) + s
it64 = it64 - a
x = x * 10
y = y * 10
i = i + 1
Loop Until it64 = 0
buffer2 = 0
For I=1 To i
buffer2(I-1)=buffer(i-I)
Next I
StrForInt64$ = MakeStr(buffer2)
If flag=1 then
StrForInt64$="-"+StrForInt64$
End If
End Function
Function Waru_Int64(A As Int64,B As Int64) As Byte
Dim I As Byte
Do
A=A-B
If 0>A then Exit Do
I=I+1
Loop
Waru_Int64=I
End Function
Function ValForInt64String(A$ As String) As Int64
ValForInt64String=ValForInt64(StrPtr(A$))
End Function
Function ValForInt64(pA As BytePtr) As Int64
Dim I As Long
Dim buffer(32) As Byte
Dim A$ As String
Dim x As Int64
A$=MakeStr(pA)
For I=0 To Len(A$)-1
buffer(I)=A$(I)-48
Next I
x=1
For I=Len(A$)-1 To 0 Step -1
If buffer(I)>10 then Exit For
ValForInt64 = ValForInt64 + Kakeru_Int64(buffer(I),x)
x = x * 10
Next I
End Function
Function Kakeru_Int64(A As Byte,B As Int64) As Int64
Dim C As QWord
Dim I As Long
C = 0
If A>1 then
For I=1 To A
C = C + B
Next I
Else
C = B
End If
Kakeru_Int64 = C
End Function
Sub InputForInt64(PrintString As String,fQuestion As Long,ByRef Inp As Int64)
Dim A$ As String
If fQuestion then
Print PrintString+"?";
Else
Print PrintString;
End If
Input A$
Inp=ValForInt64String(A$)
End Sub
Sub PrintForInt64(PrintInt64 As Int64,fReturn As Long)
Dim A$ As String
A$=StrForInt64$(PrintInt64)
If fReturn then
Print A$
Else
Print A$;
End If
End Sub
各関数の説明
ここをクリックすると各関数の説明が表示されます。 [ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]
StrForQWord$(qwd As QWord) As String
第一パラメータ:String型にするためのQWord型変数を入れてください。
概要:指定した数値を文字列に変換します。
ValForQWordString(A$ As String) As QWord
第一パラメータ:QWord型にするためのString型変数を入れてください。
概要:指定した文字列を数値に変換します。
ValForQWord(pA As BytePtr) As QWord
第一パラメータ:QWord型にするための文字列ポインタを入れてください。
概要:指定した文字列ポインタにある文字列を数値に変換します。
InputForQWord(PrintString As String,fQuestion As Long,ByRef Inp As QWord)
第一パラメータ:質問時に表示する文字列を入れてください。
第二パラメータ:疑問符をつける場合はTRUEを、つけない場合はFALSEを入れてください。
第三パラメータ:返り値を格納するためのQWord型変数を入れてください。
注意:Promptディレクティブが読み込まれている必要があります。
概要:ユーザーからのデータ入力(数値)を受け付けます。
PrintForQWord(PrintQWord As QWord,fReturn As Long)
第一パラメータ:表示するQWord型変数を入れてください。
第二パラメータ:リターンする場合はTRUEを、しない場合はFALSEを入れてください。
注意:Promptディレクティブが読み込まれている必要があります。
概要:QWord型変数を表示します。
StrForInt64$(it64 As Int64) As String
第一パラメータ:Int64型にするためのQWord型変数を入れてください。
概要:指定した数値を文字列に変換します。
ValForInt64String(A$ As String) As Int64
第一パラメータ:Int64型にするためのString型変数を入れてください。
概要:指定した文字列を数値に変換します。
ValForInt64(pA As BytePtr) As Int64
第一パラメータ:Int64型にするための文字列ポインタを入れてください。
概要:指定した文字列ポインタにある文字列を数値に変換します。
InputForInt64(PrintString As String,fQuestion As Long,ByRef Inp As Int64)
第一パラメータ:質問時に表示する文字列を入れてください。
第二パラメータ:疑問符をつける場合はTRUEを、つけない場合はFALSEを入れてください。
第三パラメータ:返り値を格納するためのInt64型変数を入れてください。
注意:Promptディレクティブが読み込まれている必要があります。
概要:ユーザーからのデータ入力(数値)を受け付けます。
PrintForInt64(PrintInt64 As Int64,fReturn As Long)
第一パラメータ:表示するInt64型変数を入れてください。
第二パラメータ:リターンする場合はTRUEを、しない場合はFALSEを入れてください。
注意:Promptディレクティブが読み込まれている必要があります。
概要:Int64型変数を表示します。
※ここに説明されていない関数は説明されている関数を支えるために設計されてある隠し関数です。よって直接使用する事を推奨しません。
QWord型とInt64型用に、Print,Input,Str$,Valの4関数を作ってみました。
バグや明らかな書き間違い、質問や意見など何かあったらどうぞ。
関数のソースコード
[hide][code]Function StrForQWord$(qwd As QWord) As String Dim buffer[32] As Byte Dim i As Long Dim a As QWord Dim s=48 As Byte Dim buffer2[32] As Byte Dim I As Long Dim x As QWord Dim y As QWord i = 0 x = 10 y = 1 debug Do a = qwd Mod x buffer[i] = Waru_QWord(a,y) + s As Byte qwd = qwd - a x = x * 10 y = y * 10 i = i + 1 Loop Until qwd = 0 buffer2[i] = 0 For I=1 To i buffer2(I-1)=buffer(i-I) Next I StrForQWord$ = MakeStr(buffer2) End Function
Function Waru_QWord(A As QWord,B As QWord) As Byte Dim C As QWord Dim I As Byte Do C=A A=A-B If A>C then Exit Do I=I+1 Loop Waru_QWord=I End Function
Function ValForQWordString(A$ As String) As QWord ValForQWordString=ValForQWord(StrPtr(A$)) End Function
Function ValForQWord(pA As BytePtr) As QWord Dim I As Long Dim buffer(32) As Byte Dim A$ As String Dim x As QWord A$=MakeStr(pA) For I=0 To Len(A$)-1 buffer(I)=A$(I)-48 Next I x=1 For I=Len(A$)-1 To 0 Step -1 If buffer(I)>10 then Exit For ValForQWord = ValForQWord + Kakeru_QWord(buffer(I),x) x = x * 10 Next I End Function
Function Kakeru_QWord(A As Byte,B As QWord) As QWord Dim C As QWord Dim I As Long C = 0 If A>1 then For I=1 To A C = C + B Next I Else C = B End If Kakeru_QWord = C End Function
Sub InputForQWord(PrintString As String,fQuestion As Long,ByRef Inp As QWord)
Dim A$ As String
If fQuestion then Print PrintString+"?"; Else Print PrintString; End If Input A$ Inp=ValForQWordString(A$) End Sub
Sub PrintForQWord(PrintQWord As QWord,fReturn As Long) Dim A$ As String A$=StrForQWord$(PrintQWord) If fReturn then Print A$ Else Print A$; End If End Sub
Function StrForInt64$(it64 As Int64) As String Dim buffer[32] As Byte Dim i As Long Dim a As QWord Dim s=48 As Byte Dim buffer2[32] As Byte Dim I As Long Dim x As QWord Dim y As QWord Dim flag=0 As Long If it64<0 then flag=1 it64 = -1 * it64 End If i = 0 x = 10 y = 1 Do a = it64 Mod x buffer[i] = Waru_Int64(a,y) + s it64 = it64 - a x = x * 10 y = y * 10 i = i + 1 Loop Until it64 = 0 buffer2[i] = 0 For I=1 To i buffer2(I-1)=buffer(i-I) Next I StrForInt64$ = MakeStr(buffer2) If flag=1 then StrForInt64$="-"+StrForInt64$ End If End Function
Function Waru_Int64(A As Int64,B As Int64) As Byte Dim I As Byte Do A=A-B If 0>A then Exit Do I=I+1 Loop Waru_Int64=I End Function
Function ValForInt64String(A$ As String) As Int64 ValForInt64String=ValForInt64(StrPtr(A$)) End Function
Function ValForInt64(pA As BytePtr) As Int64 Dim I As Long Dim buffer(32) As Byte Dim A$ As String Dim x As Int64 A$=MakeStr(pA) For I=0 To Len(A$)-1 buffer(I)=A$(I)-48 Next I x=1 For I=Len(A$)-1 To 0 Step -1 If buffer(I)>10 then Exit For ValForInt64 = ValForInt64 + Kakeru_Int64(buffer(I),x) x = x * 10 Next I End Function
Function Kakeru_Int64(A As Byte,B As Int64) As Int64 Dim C As QWord Dim I As Long C = 0 If A>1 then For I=1 To A C = C + B Next I Else C = B End If Kakeru_Int64 = C End Function
Sub InputForInt64(PrintString As String,fQuestion As Long,ByRef Inp As Int64)
Dim A$ As String
If fQuestion then Print PrintString+"?"; Else Print PrintString; End If Input A$ Inp=ValForInt64String(A$) End Sub
Sub PrintForInt64(PrintInt64 As Int64,fReturn As Long) Dim A$ As String A$=StrForInt64$(PrintInt64) If fReturn then Print A$ Else Print A$; End If End Sub[/code][/hide]
各関数の説明 [hide=ここをクリックすると各関数の説明が表示されます。] StrForQWord$(qwd As QWord) As String 第一パラメータ:String型にするためのQWord型変数を入れてください。 概要:指定した数値を文字列に変換します。
ValForQWordString(A$ As String) As QWord 第一パラメータ:QWord型にするためのString型変数を入れてください。 概要:指定した文字列を数値に変換します。
ValForQWord(pA As BytePtr) As QWord 第一パラメータ:QWord型にするための文字列ポインタを入れてください。 概要:指定した文字列ポインタにある文字列を数値に変換します。
InputForQWord(PrintString As String,fQuestion As Long,ByRef Inp As QWord)
第一パラメータ:質問時に表示する文字列を入れてください。 第二パラメータ:疑問符をつける場合はTRUEを、つけない場合はFALSEを入れてください。 第三パラメータ:返り値を格納するためのQWord型変数を入れてください。 注意:Promptディレクティブが読み込まれている必要があります。 概要:ユーザーからのデータ入力(数値)を受け付けます。
PrintForQWord(PrintQWord As QWord,fReturn As Long)
第一パラメータ:表示するQWord型変数を入れてください。 第二パラメータ:リターンする場合はTRUEを、しない場合はFALSEを入れてください。 注意:Promptディレクティブが読み込まれている必要があります。 概要:QWord型変数を表示します。
StrForInt64$(it64 As Int64) As String 第一パラメータ:Int64型にするためのQWord型変数を入れてください。 概要:指定した数値を文字列に変換します。
ValForInt64String(A$ As String) As Int64 第一パラメータ:Int64型にするためのString型変数を入れてください。 概要:指定した文字列を数値に変換します。
ValForInt64(pA As BytePtr) As Int64 第一パラメータ:Int64型にするための文字列ポインタを入れてください。 概要:指定した文字列ポインタにある文字列を数値に変換します。
InputForInt64(PrintString As String,fQuestion As Long,ByRef Inp As Int64)
第一パラメータ:質問時に表示する文字列を入れてください。 第二パラメータ:疑問符をつける場合はTRUEを、つけない場合はFALSEを入れてください。 第三パラメータ:返り値を格納するためのInt64型変数を入れてください。 注意:Promptディレクティブが読み込まれている必要があります。 概要:ユーザーからのデータ入力(数値)を受け付けます。
PrintForInt64(PrintInt64 As Int64,fReturn As Long)
第一パラメータ:表示するInt64型変数を入れてください。 第二パラメータ:リターンする場合はTRUEを、しない場合はFALSEを入れてください。 注意:Promptディレクティブが読み込まれている必要があります。 概要:Int64型変数を表示します。
※ここに説明されていない関数は説明されている関数を支えるために設計されてある隠し関数です。よって直接使用する事を推奨しません。 [/hide]
QWord型とInt64型用に、Print,Input,Str$,Valの4関数を作ってみました。 バグや明らかな書き間違い、質問や意見など何かあったらどうぞ。
|
|
|
投稿記事 |
Posted: 2006年4月05日(水) 06:29 |
|
|
|
|