ab.com コミュニティ https://www.activebasic.com/forum/ |
|
64bit変数の計算結果がおかしい https://www.activebasic.com/forum/viewtopic.php?t=1711 |
ページ 1 / 1 |
作成者: | OverTaker [ 2006年12月01日(金) 13:34 ] |
記事の件名: | 64bit変数の計算結果がおかしい |
64bit変数において、次のような計算をすると、なぜか10^16あたりから正しく計算できなくなってしまいます。本来valueには10^16-1が入りますが、なぜかvalueに10^16が入ってしまいます。 ActiveBasic5.0で確認しました。 コード: Dim value As Int64 Dim i As Long For i = 0 To 18 value = 10^i-1 debug Next |
作成者: | イグトランス [ 2006年12月01日(金) 16:59 ] |
記事の件名: | |
^演算子の実体は,basic/function.sbpにあるpow関数ではないでしょうか? そうだとすれば,Double型で演算されて情報落ちになっているのだと思います。 |
作成者: | イグトランス [ 2006年12月02日(土) 00:00 ] |
記事の件名: | |
試しにOLEオートメーションのVARIANT型(内部形式:Decimal(十進小数)型)に変換し,VARIANT型の演算関数で行わせたところ正しい結果にさせることができました。 ただし,これはもはや64ビット演算ではありません。 [ここをクリックすると内容が表示されます] コード: Class VARIANT Public vt As Word wReserved1 As Word wReserved2 As Word wReserved3 As Word llVal As Int64 Function bstrVal() As BSTR Return GetDWord(VarPtr(llVal)) End Function End Class TypeDef VARTYPE = Word Declare Function VarDiv Lib "oleaut32.dll" (ByRef lhs As VARIANT, ByRef rhs As VARIANT, ByRef result As VARIANT) As HRESULT Declare Function VarCat Lib "oleaut32.dll" (ByRef lhs As VARIANT, ByRef rhs As VARIANT, ByRef result As VARIANT) As HRESULT Declare Function VarInt Lib "oleaut32.dll" (ByRef in As VARIANT, ByRef result As VARIANT) As HRESULT Declare Function VariantChangeType Lib "oleaut32.dll" (ByRef vargDest As VARIANT, ByRef varSrc As VARIANT, Flags As Word, vt As VARTYPE) As HRESULT Declare Function VariantClear Lib "oleaut32.dll" (ByRef varg As VARIANT) As HRESULT Declare Function MessageBoxW Lib "user32" (hWnd As HWND, pText As *WCHAR, pCaption As *WCHAR, uType As DWord) As Long Declare Function wsprintfW CDECL Lib "user32" (pText As *WCHAR, pFormat As *WCHAR, ...) As Long Const VT_EMPTY = 0 Const VT_BSTR = 8 Const VT_I8 = 20 Const VT_DECIMAL = 14 Dim n As VARIANT, d As VARIANT, result As VARIANT, empty As VARIANT, tmp As VARIANT n.vt = VT_I8 n.llVal = 10 ^ 18 - 1 d.vt = VT_I8 d.llVal = 10 result.vt = VT_EMPTY VariantChangeType(n, n, 0, VT_DECIMAL) ' n = CDec(n) CDecはVBの関数 VariantChangeType(d, d, 0, VT_DECIMAL) ' d = CDec(d) Dim hr As HRESULT hr = VarDiv(n, d, result) ' result = n / d empty.vt = VT_EMPTY tmp.vt = VT_EMPTY VariantChangeType(n, n, 0, VT_BSTR) 'n = CStr(n) ABではn = Str$(n)に近い VariantChangeType(d, d, 0, VT_BSTR) VarInt(result, result) ' result = Int(result) 'ABのIntと同じ意味 VariantChangeType(result, result, 0, VT_BSTR) Dim buf[1024] As WCHAR Dim format[1024] As WCHAR, i As Long, p As *Byte, len As Long p = "%s / %s = %s" len = lstrlen(p) For i = 0 To len format = p ' ワイド文字へ変換 Next wsprintfW(buf, format, n.bstrVal, d.bstrVal, result.bstrVal) MessageBoxW(0, buf, 0, MB_OK) VariantClear(n) VariantClear(d) VariantClear(result) End VARIANT型はメンバ変数vtに現在保持しているデータ型を格納し,llValの部分(実際には共用体)に実際のデータを格納すると言う形式です。 また十進型はVBA 6のリファレンスで次のように説明されている型です。 引用: 10 進型 (Decimal)
10 の累乗の指数によって算出される、10 進数を格納するデータ型。小数点以下の桁数が 0 の場合 (小数部分を持たない場合)、絶対値の最大値は 79,228,162,514,264,337,593,543,950,335 です。小数点以下 28 桁の場合、絶対値の最大値は 7.9228162514264337593543950335 です。10 進型 (Decimal) で表される絶対値の最小値は、0 を除いた場合、0.0000000000000000000000000001 です。 |
作成者: | OverTaker [ 2006年12月02日(土) 00:09 ] |
記事の件名: | |
わざわざコードまでありがとうございます。 これを使うかはまだわからないですが、参考にさせていただきます。こちらでもいい方法を模索したいと思います。 |
作成者: | イグトランス [ 2006年12月07日(木) 23:32 ] |
記事の件名: | |
今更気付いたのですが,これは単にキャストすれば良かっただけのような気がします。 コード: Dim value As Int64 Dim i As Long For i = 0 To 18 value = (10 ^ i) As Int64 - 1 debug Next |
ページ 1 / 1 | 全ての表示時間は UTC+09:00 です |
Powered by phpBB® Forum Software © phpBB Limited https://www.phpbb.com/ |