none
64ビット演算でバグ出ると思うのですが RRS feed

  • 質問

  • 1の演算) &HFEDCBA987654321 And (256^6-1)  ()が必要でした
    2の演算)  &HFEDCBA987654321 Mod 256^6

    上記の二つの演算は、同じ答えが出ると思うのですが
    実際に演算すると下記のように、Mod では
    下位ビットが0になってしまいます
    Int64を使った処理の場合、正しく無いのは
    Frameworkのバグ? ちなみに VB2005での結果です
    他の言語では確認していません

    HEX(&HFEDCBA987654321 and 256^6-1)

    "CBA987654321"

    HEX(&HFEDCBA987654321 mod 256^6)

    "CBA987654300"

    2009年2月23日 7:17

回答

  • 外池と申します。皆さんの回答を総合する感じになるのですが・・・、

    VBのMOD演算子は、被除数も除数も整数型なら、整数型で演算してくれると思います。で、問題は、べき乗に「^」演算子を使ってしまっていることで、この演算の結果が倍精度浮動小数点数Double型になって、そのためMod演算子の計算もDouble型になってしまったのでしょう。

    ちなみに、暗黙の型変換を許していませんか(Option Strict Off)? 暗黙の型変換を許さない(Option Strict On)場合は、And演算子の後ろの「256^6-1」のところで警告が出ます。And演算子は整数型しか受け付けないので、「256^6-1」のDouble型の結果を変換できない旨の表示が出ます。

    「256^6」や、これから1を引いた数は高々49ビットなので、Double型でも正確に表現できますので、CLngで64bit整数に正確に変換できます。したがって、

    &HFEDCBA987654321 And CLng(256 ^ 6 - 1)
    &HFEDCBA987654321 Mod CLng(256 ^ 6)

    これらは、同じ結果になります。

    (整数型のみを扱うことを意図している場合、べき乗「^」演算子は鬼門です。できるだけ使わない方がいいです。型が変わるし、遅いし。)


    (ホームページを再開しました)
    • 回答としてマーク sk7474 2009年3月11日 8:59
    2009年2月24日 0:44
  • VB の MOD は、浮動小数点で計算されるので、大きな数を扱うと桁落ちします。
    • 回答としてマーク sk7474 2009年3月11日 9:01
    2009年2月23日 8:17
    • 回答としてマーク sk7474 2009年3月11日 9:01
    2009年2月23日 8:22
  • 加えて ^ 演算子も Double型なので有効精度は最大で52bitぐらいでしょうか。
    • 回答としてマーク sk7474 2009年3月11日 9:01
    2009年2月23日 8:33

すべての返信

  • VB の MOD は、浮動小数点で計算されるので、大きな数を扱うと桁落ちします。
    • 回答としてマーク sk7474 2009年3月11日 9:01
    2009年2月23日 8:17
    • 回答としてマーク sk7474 2009年3月11日 9:01
    2009年2月23日 8:22
  • 加えて ^ 演算子も Double型なので有効精度は最大で52bitぐらいでしょうか。
    • 回答としてマーク sk7474 2009年3月11日 9:01
    2009年2月23日 8:33
  • 外池と申します。皆さんの回答を総合する感じになるのですが・・・、

    VBのMOD演算子は、被除数も除数も整数型なら、整数型で演算してくれると思います。で、問題は、べき乗に「^」演算子を使ってしまっていることで、この演算の結果が倍精度浮動小数点数Double型になって、そのためMod演算子の計算もDouble型になってしまったのでしょう。

    ちなみに、暗黙の型変換を許していませんか(Option Strict Off)? 暗黙の型変換を許さない(Option Strict On)場合は、And演算子の後ろの「256^6-1」のところで警告が出ます。And演算子は整数型しか受け付けないので、「256^6-1」のDouble型の結果を変換できない旨の表示が出ます。

    「256^6」や、これから1を引いた数は高々49ビットなので、Double型でも正確に表現できますので、CLngで64bit整数に正確に変換できます。したがって、

    &HFEDCBA987654321 And CLng(256 ^ 6 - 1)
    &HFEDCBA987654321 Mod CLng(256 ^ 6)

    これらは、同じ結果になります。

    (整数型のみを扱うことを意図している場合、べき乗「^」演算子は鬼門です。できるだけ使わない方がいいです。型が変わるし、遅いし。)


    (ホームページを再開しました)
    • 回答としてマーク sk7474 2009年3月11日 8:59
    2009年2月24日 0:44
  • 質問をなげかけたまま、寝込んでしまい
    回答された方へのお礼も遅れてしまいました
    申し訳有りません

    外池さんの言われた事で納得です
    64ビット演算が出来るのは、とても都合良く
    と言うのは、ビット分解してデータを振り分けている為に
    64ビットだと、64件分の処理が一度で出来るメリット有り
    都合良かったのですが、途中で誤作動を起こして
    頭を悩ましていました

    通常はビット演算なので、2^n の様な形で使っていました
    Data-=2^n<>0 の様にですが、これもべき乗「^」演算子は使わない方がよさそうで

    他に代用はちょっと頭を悩ましそうです
    ビットシフト演算子が有りますが、他にビット処理出来る方法が有るのでしょうか
    これから探します
    回答された皆さん、本当に有難うございました

    2009年3月3日 19:31
  • こんにちは。中川俊輔 です。

    皆様、回答ありがとうございます。

    クララさん、フォーラムのご利用ありがとうございます。
    勝手ながら、有用な情報と思われる回答へ回答マークをつけさせていただきました。

    今後ともフォーラムをよろしくお願いします。
    それでは!
    マイクロソフト株式会社 フォーラム オペレータ 中川 俊輔
    2009年3月11日 9:04