none
お願い教えて!DWORD64の型について RRS feed

  • 質問

  • DWORD64の型の変数に、格納できる範囲はどこまでなんでしょうか?

    64とあるので、64bit変数だと思っていました。どころが、

    DOWRD64_1 = int_1 * int_2 * (int_3 + int_4 * int_5)

    のような計算式で算出した結果がDOWRD64に格納できませんでした。

    32bitを超える数になると、突然ありえない値になってしまいます。

    どころが、

    DWORD64_2 = int_3 + int_4 * int_5

    DWORD64_1 = int_1 * int_2 * DWORD64_2

    とすると、正しく値が格納されます。これは、いったいどうなっているのか、誰か教えてください。

    よろしくお願いします。

    動作環境:Windows7・Vista

    開発言語:Visual Studio2005・2010 C++

     

    2011年4月4日 8:55

回答

  • >int_3 + int_4 * int_5
    これは32bitで計算され、32bit以内で収まっている

    >int_1 * int_2 * DWORD64_2
    int_1 * int_2は32bitで計算され、32bit以内で収まっている。
    * DWORD64_2はDWORD64_2があるので、64bitで計算されている。

    ということでしょう。

    [Standard Conversions]
      http://msdn.microsoft.com/en-us/library/aetzh118.aspx

    >たまたまということなんでしょうか?
    int_X変数がとりうる値の範囲が分かりませんが、intの最小値から最大値までとりうるのなら、
    ”たまたま”ということになります。

    2011年4月4日 12:19

すべての返信

  • >DWORD64の型の変数に、格納できる範囲はどこまでなんでしょうか?
    >64とあるので、64bit変数だと思っていました
    64bitです。

    typedef unsigned __int64 DWORD64;

    #define INT64_MIN       (-9223372036854775807i64 - 1)
    #define INT64_MAX       9223372036854775807i64

     >32bitを超える数になると、突然ありえない値になってしまいます。
    int_X変数は32bitですか?計算途中でOverflowしているのでしょう。
    DWORD64でcastするか、DWORD64の変数に値を入れてから計算してみてください。

    2011年4月4日 9:24
  • やっぱり、64bitなんですね。

    確かに、intは64bitではないです。

    なんとなくは、Overflowを起こしているのはわかるのですが

    DWORD64_2 = int_3 + int_4 * int_5

    DWORD64_1 = int_1 * int_2 * DWORD64_2

    の計算で正しい値がはいってくるのはたまたまということなんでしょうか?

     

    2011年4月4日 10:42
  • 予想できるのは int_3 + int_4 * int_5 の段階で、まだ32bitの範囲でオーバーフローしていないということでしょうか。

    キャストするとどうなるか調べてみてください。

    DOWRD64_1 = int_1 * int_2 * static_cast<DWORD64>(int_3 + int_4 * int_5)

     

     

    2011年4月4日 11:11
  • >int_3 + int_4 * int_5
    これは32bitで計算され、32bit以内で収まっている

    >int_1 * int_2 * DWORD64_2
    int_1 * int_2は32bitで計算され、32bit以内で収まっている。
    * DWORD64_2はDWORD64_2があるので、64bitで計算されている。

    ということでしょう。

    [Standard Conversions]
      http://msdn.microsoft.com/en-us/library/aetzh118.aspx

    >たまたまということなんでしょうか?
    int_X変数がとりうる値の範囲が分かりませんが、intの最小値から最大値までとりうるのなら、
    ”たまたま”ということになります。

    2011年4月4日 12:19
  • 外池と申します。

    「+」や「*」の演算ごとに、オーバーフロウするかどうかを考えながら式を書かないといけません。式全体で結果を64bit整数型に代入するからと言って、安心してはいけないわけです。

    しかるべきドキュメントを調べれば、演算子ごとに、計算する数値の型の組み合わせによって、どのように型変換されて演算されるか整理して載っていますので、確認されることをお薦めします。(整数型と浮動小数点型の組み合わせなんかも、要注意だったりします。)

    ごくごく一般的な注意ですので、今後の参考にして頂ければ幸いです。


    (ホームページを再開しました)
    2011年4月5日 0:12
  • 「暗黙の型変換」というキーワードで調べて見てください。

    たぶん、参考になる記事がたくさん出てくると思います。

    暗黙の型変換は入門書の中でも比較的前の方で出てくる話ですから
    入門書を持っておられるのでしたら再度読み直される事をお勧めします。
    この時、開発環境の入門書を読むのではなくてC++言語の入門書を読まれる事をお勧めします。
    開発環境の入門書では開発環境の使い方はわかってもC++言語の使い方までは学べません。

     


    解決した時は、参考になったレスポンスの所にある[回答としてマーク]ボタンをクリックしてスレッドを締めましょう。
    2011年4月5日 6:37
  • ざっぱに言うと
    DOWRD64_1 = int_1 * int_2 * (int_3 + int_4 * int_5) は、
    1.1 int_1 * int_2が評価されintに格納(intA)
    1.2 int_4 * int_5が評価されintに格納(intB)
    1.3 int_3 + intBが評価されintに格納(intC)
    1.4 intA * intCが評価されintに格納(intD)
    1.5 DWORD64_1 = intDが評価されDWORD64に変換

    DWORD64_2 = int_3 + int_4 * int_5 は
    2.1 int_4 * int_5が評価されintに格納(intA)
    2.2 int_3 + intAが評価されintに格納(intB)
    2.3 DWORD64_2 = intBが評価されDWORD64に変換

    DWORD64_1 = int_1 * int_2 * DWORD64_2 は
    2.4 int_1 * int_2が評価されintに格納(intC)
    2.5 intC * DWORD64_2が評価されDWORD64に格納( DWORD64_X)
    2.6 DWORD64_1 = DWORD64_Xが評価される

    1.xと2.xの違いは、1.4と、2.5の処理の違い、および、
    1.5と2.6の処理の違いによるものではないでしょうか。
    最初の式も、中間でオーバーフローしないように適当な位置でDWORD64にキャストすれば
    正常に計算されるはずですね。



    2011年4月5日 7:43
  • みなさん、ありがとうございます。返信が遅くなり、大変申し訳ありません。

    もう一度、確認してみます。

     

     

    2011年4月6日 1:20
  • 解決済みですが、x86プロセッサに詳しい方向けにマニアックな__emul()関数があります。

    DWORD64_1 = int_1 * int_2 * ( int_3 + __emul( int_4, int_5 ) );

    もしくは

    DWORD64_1 = __emul( int_1, int_2 ) * ( int_3 + __emul( int_4, int_5 ) );

    とできます。

    2011年4月7日 2:01