QA@IT
«回答へ戻る

VC

942
 2147483647: i(2147483647)
 2147483648: x(2147483648)
 ```
+
+---
+
+ちなみに VC で試すと次の通りになり
+
+```cpp
+#include <iostream>
+#include <limits>
+#include <typeinfo>
+#define PRINT_TYPE(x) std::cout << #x << ": " << typeid(x).name() << std::endl
+#define PRINT_VALUE(x) std::cout << #x << ": " << typeid(x).name() << "(" << x << ")" <<std::endl
+int main()
+{
+    PRINT_TYPE(int);
+    PRINT_TYPE(long int);
+    PRINT_TYPE(long long int);
+    PRINT_TYPE(unsigned int);
+    PRINT_TYPE(unsigned long int);
+    PRINT_TYPE(unsigned long long int);
+    PRINT_VALUE(2147483647);
+    PRINT_VALUE(2147483648);
+    PRINT_VALUE(-2147483648);
+    PRINT_VALUE(-0x80000000);
+    PRINT_VALUE(-0x80000000l);
+    return 0;
+}
+```
+
+```
+int: int
+long int: long
+long long int: __int64
+unsigned int: unsigned int
+unsigned long int: unsigned long
+unsigned long long int: unsigned __int64
+2147483647: int(2147483647)
+2147483648: unsigned long(2147483648)
+-2147483648: unsigned long(2147483648)
+-0x80000000: unsigned int(2147483648)
+-0x80000000l: unsigned long(2147483648)
+```
+
+この時の警告メッセージで検索するとそれらしいことが書かれています。
+
+[コンパイラの警告 (レベル 2) C4146](http://msdn.microsoft.com/ja-jp/library/4kh09110 "コンパイラの警告 (レベル 2) C4146")
+
+> 2147483648 の型は int ではなく unsigned int
+
+と書かれているのが疑問ですが。

私は-2147483648も-0x80000000もi(int)とみなされると理解していましたが、
それぞれl(long int)、j(unsigned int)とみなされています。
そのため-2147483648と-0x80000000を比較しても一致しません(違う値と見なされているため)。

正確な仕様とかは詳しくないので判りませんが、次の通りになっているのだと思われます。

  • -21474836482147483648 が long で単項演算子 -0xFFFFFFFF80000000-2147483648 (long)
  • -0x800000000x80000000 が unsigned int で単項演算子 -0x800000002147483648 (unsigned int)

念の為ideoneでも実行してみました:
http://ideone.com/ErUnhL
こちらはリテラルがそれぞれm(unsigned long int)、j(unsigned int)のように両方共unsignedと見なされています。

32ビット環境のようなので次の通り・・・

  • -21474836482147483648 が unsigned int で単項演算子 -0x800000002147483648 (unsigned int)
  • -0x800000000x80000000 が unsigned int で単項演算子 -0x800000002147483648 (unsigned int)

と思ったのですが -2147483648unsigned long になっていますね・・・

なぜかは判りませんが 2147483648unsigned long になるようです。

#include <iostream>
#include <limits>
#include <typeinfo>
#define PRINT_TYPE(x) std::cout << #x << ": " << typeid(x).name() << std::endl
#define PRINT_VALUE(x) std::cout << #x << ": " << typeid(x).name() << "(" << x << ")" <<std::endl
int main()
{
    PRINT_TYPE(int);
    PRINT_TYPE(long int);
    PRINT_TYPE(long long int);
    PRINT_TYPE(unsigned int);
    PRINT_TYPE(unsigned long int);
    PRINT_TYPE(unsigned long long int);
    PRINT_VALUE(2147483647);
    PRINT_VALUE(2147483648);
    return 0;
}
int: i
long int: l
long long int: x
unsigned int: j
unsigned long int: m
unsigned long long int: y
2147483647: i(2147483647)
2147483648: m(2147483648)

c++11 だとまた挙動が変わるようです。

int: i
long int: l
long long int: x
unsigned int: j
unsigned long int: m
unsigned long long int: y
2147483647: i(2147483647)
2147483648: x(2147483648)

ちなみに VC で試すと次の通りになり

#include <iostream>
#include <limits>
#include <typeinfo>
#define PRINT_TYPE(x) std::cout << #x << ": " << typeid(x).name() << std::endl
#define PRINT_VALUE(x) std::cout << #x << ": " << typeid(x).name() << "(" << x << ")" <<std::endl
int main()
{
    PRINT_TYPE(int);
    PRINT_TYPE(long int);
    PRINT_TYPE(long long int);
    PRINT_TYPE(unsigned int);
    PRINT_TYPE(unsigned long int);
    PRINT_TYPE(unsigned long long int);
    PRINT_VALUE(2147483647);
    PRINT_VALUE(2147483648);
    PRINT_VALUE(-2147483648);
    PRINT_VALUE(-0x80000000);
    PRINT_VALUE(-0x80000000l);
    return 0;
}
int: int
long int: long
long long int: __int64
unsigned int: unsigned int
unsigned long int: unsigned long
unsigned long long int: unsigned __int64
2147483647: int(2147483647)
2147483648: unsigned long(2147483648)
-2147483648: unsigned long(2147483648)
-0x80000000: unsigned int(2147483648)
-0x80000000l: unsigned long(2147483648)

この時の警告メッセージで検索するとそれらしいことが書かれています。

コンパイラの警告 (レベル 2) C4146

2147483648 の型は int ではなく unsigned int

と書かれているのが疑問ですが。

> 私は-2147483648も-0x80000000もi(int)とみなされると理解していましたが、
> それぞれl(long int)、j(unsigned int)とみなされています。
> そのため-2147483648と-0x80000000を比較しても一致しません(違う値と見なされているため)。

正確な仕様とかは詳しくないので判りませんが、次の通りになっているのだと思われます。

 - `-2147483648` は `2147483648` が long で単項演算子 `-` で `0xFFFFFFFF80000000` → `-2147483648 (long)`
 - `-0x80000000` は `0x80000000` が unsigned int で単項演算子 `-` で `0x80000000` → `2147483648 (unsigned int)`


> 念の為ideoneでも実行してみました:
> http://ideone.com/ErUnhL
> こちらはリテラルがそれぞれm(unsigned long int)、j(unsigned int)のように両方共unsignedと見なされています。

32ビット環境のようなので次の通り・・・

 - `-2147483648` は `2147483648` が unsigned int で単項演算子 `-` で `0x80000000` → `2147483648 (unsigned int)`。
 - `-0x80000000` は `0x80000000` が unsigned int で単項演算子 `-` で `0x80000000` → `2147483648 (unsigned int)`。

と思ったのですが `-2147483648` は `unsigned long` になっていますね・・・

なぜかは判りませんが `2147483648` は `unsigned long` になるようです。

```cpp
#include <iostream>
#include <limits>
#include <typeinfo>
#define PRINT_TYPE(x) std::cout << #x << ": " << typeid(x).name() << std::endl
#define PRINT_VALUE(x) std::cout << #x << ": " << typeid(x).name() << "(" << x << ")" <<std::endl
int main()
{
    PRINT_TYPE(int);
    PRINT_TYPE(long int);
    PRINT_TYPE(long long int);
    PRINT_TYPE(unsigned int);
    PRINT_TYPE(unsigned long int);
    PRINT_TYPE(unsigned long long int);
    PRINT_VALUE(2147483647);
    PRINT_VALUE(2147483648);
    return 0;
}
```

```
int: i
long int: l
long long int: x
unsigned int: j
unsigned long int: m
unsigned long long int: y
2147483647: i(2147483647)
2147483648: m(2147483648)
```

c++11 だとまた挙動が変わるようです。

```
int: i
long int: l
long long int: x
unsigned int: j
unsigned long int: m
unsigned long long int: y
2147483647: i(2147483647)
2147483648: x(2147483648)
```

---

ちなみに VC で試すと次の通りになり

```cpp
#include <iostream>
#include <limits>
#include <typeinfo>
#define PRINT_TYPE(x) std::cout << #x << ": " << typeid(x).name() << std::endl
#define PRINT_VALUE(x) std::cout << #x << ": " << typeid(x).name() << "(" << x << ")" <<std::endl
int main()
{
    PRINT_TYPE(int);
    PRINT_TYPE(long int);
    PRINT_TYPE(long long int);
    PRINT_TYPE(unsigned int);
    PRINT_TYPE(unsigned long int);
    PRINT_TYPE(unsigned long long int);
    PRINT_VALUE(2147483647);
    PRINT_VALUE(2147483648);
    PRINT_VALUE(-2147483648);
    PRINT_VALUE(-0x80000000);
    PRINT_VALUE(-0x80000000l);
    return 0;
}
```

```
int: int
long int: long
long long int: __int64
unsigned int: unsigned int
unsigned long int: unsigned long
unsigned long long int: unsigned __int64
2147483647: int(2147483647)
2147483648: unsigned long(2147483648)
-2147483648: unsigned long(2147483648)
-0x80000000: unsigned int(2147483648)
-0x80000000l: unsigned long(2147483648)
```

この時の警告メッセージで検索するとそれらしいことが書かれています。

[コンパイラの警告 (レベル 2) C4146](http://msdn.microsoft.com/ja-jp/library/4kh09110 "コンパイラの警告 (レベル 2) C4146")

> 2147483648 の型は int ではなく unsigned int

と書かれているのが疑問ですが。

syntax highlighting cpp

942
 
 なぜかは判りませんが `2147483648` は `unsigned long` になるようです。
 
-```
+```cpp
 #include <iostream>
 #include <limits>
 #include <typeinfo>

私は-2147483648も-0x80000000もi(int)とみなされると理解していましたが、
それぞれl(long int)、j(unsigned int)とみなされています。
そのため-2147483648と-0x80000000を比較しても一致しません(違う値と見なされているため)。

正確な仕様とかは詳しくないので判りませんが、次の通りになっているのだと思われます。

  • -21474836482147483648 が long で単項演算子 -0xFFFFFFFF80000000-2147483648 (long)
  • -0x800000000x80000000 が unsigned int で単項演算子 -0x800000002147483648 (unsigned int)

念の為ideoneでも実行してみました:
http://ideone.com/ErUnhL
こちらはリテラルがそれぞれm(unsigned long int)、j(unsigned int)のように両方共unsignedと見なされています。

32ビット環境のようなので次の通り・・・

  • -21474836482147483648 が unsigned int で単項演算子 -0x800000002147483648 (unsigned int)
  • -0x800000000x80000000 が unsigned int で単項演算子 -0x800000002147483648 (unsigned int)

と思ったのですが -2147483648unsigned long になっていますね・・・

なぜかは判りませんが 2147483648unsigned long になるようです。

#include <iostream>
#include <limits>
#include <typeinfo>
#define PRINT_TYPE(x) std::cout << #x << ": " << typeid(x).name() << std::endl
#define PRINT_VALUE(x) std::cout << #x << ": " << typeid(x).name() << "(" << x << ")" <<std::endl
int main()
{
    PRINT_TYPE(int);
    PRINT_TYPE(long int);
    PRINT_TYPE(long long int);
    PRINT_TYPE(unsigned int);
    PRINT_TYPE(unsigned long int);
    PRINT_TYPE(unsigned long long int);
    PRINT_VALUE(2147483647);
    PRINT_VALUE(2147483648);
    return 0;
}
int: i
long int: l
long long int: x
unsigned int: j
unsigned long int: m
unsigned long long int: y
2147483647: i(2147483647)
2147483648: m(2147483648)

c++11 だとまた挙動が変わるようです。

int: i
long int: l
long long int: x
unsigned int: j
unsigned long int: m
unsigned long long int: y
2147483647: i(2147483647)
2147483648: x(2147483648)
> 私は-2147483648も-0x80000000もi(int)とみなされると理解していましたが、
> それぞれl(long int)、j(unsigned int)とみなされています。
> そのため-2147483648と-0x80000000を比較しても一致しません(違う値と見なされているため)。

正確な仕様とかは詳しくないので判りませんが、次の通りになっているのだと思われます。

 - `-2147483648` は `2147483648` が long で単項演算子 `-` で `0xFFFFFFFF80000000` → `-2147483648 (long)`
 - `-0x80000000` は `0x80000000` が unsigned int で単項演算子 `-` で `0x80000000` → `2147483648 (unsigned int)`


> 念の為ideoneでも実行してみました:
> http://ideone.com/ErUnhL
> こちらはリテラルがそれぞれm(unsigned long int)、j(unsigned int)のように両方共unsignedと見なされています。

32ビット環境のようなので次の通り・・・

 - `-2147483648` は `2147483648` が unsigned int で単項演算子 `-` で `0x80000000` → `2147483648 (unsigned int)`。
 - `-0x80000000` は `0x80000000` が unsigned int で単項演算子 `-` で `0x80000000` → `2147483648 (unsigned int)`。

と思ったのですが `-2147483648` は `unsigned long` になっていますね・・・

なぜかは判りませんが `2147483648` は `unsigned long` になるようです。

```cpp
#include <iostream>
#include <limits>
#include <typeinfo>
#define PRINT_TYPE(x) std::cout << #x << ": " << typeid(x).name() << std::endl
#define PRINT_VALUE(x) std::cout << #x << ": " << typeid(x).name() << "(" << x << ")" <<std::endl
int main()
{
    PRINT_TYPE(int);
    PRINT_TYPE(long int);
    PRINT_TYPE(long long int);
    PRINT_TYPE(unsigned int);
    PRINT_TYPE(unsigned long int);
    PRINT_TYPE(unsigned long long int);
    PRINT_VALUE(2147483647);
    PRINT_VALUE(2147483648);
    return 0;
}
```

```
int: i
long int: l
long long int: x
unsigned int: j
unsigned long int: m
unsigned long long int: y
2147483647: i(2147483647)
2147483648: m(2147483648)
```

c++11 だとまた挙動が変わるようです。

```
int: i
long int: l
long long int: x
unsigned int: j
unsigned long int: m
unsigned long long int: y
2147483647: i(2147483647)
2147483648: x(2147483648)
```

回答を投稿

私は-2147483648も-0x80000000もi(int)とみなされると理解していましたが、
それぞれl(long int)、j(unsigned int)とみなされています。
そのため-2147483648と-0x80000000を比較しても一致しません(違う値と見なされているため)。

正確な仕様とかは詳しくないので判りませんが、次の通りになっているのだと思われます。

  • -21474836482147483648 が long で単項演算子 -0xFFFFFFFF80000000-2147483648 (long)
  • -0x800000000x80000000 が unsigned int で単項演算子 -0x800000002147483648 (unsigned int)

念の為ideoneでも実行してみました:
http://ideone.com/ErUnhL
こちらはリテラルがそれぞれm(unsigned long int)、j(unsigned int)のように両方共unsignedと見なされています。

32ビット環境のようなので次の通り・・・

  • -21474836482147483648 が unsigned int で単項演算子 -0x800000002147483648 (unsigned int)
  • -0x800000000x80000000 が unsigned int で単項演算子 -0x800000002147483648 (unsigned int)

と思ったのですが -2147483648unsigned long になっていますね・・・

なぜかは判りませんが 2147483648unsigned long になるようです。

#include <iostream>
#include <limits>
#include <typeinfo>
#define PRINT_TYPE(x) std::cout << #x << ": " << typeid(x).name() << std::endl
#define PRINT_VALUE(x) std::cout << #x << ": " << typeid(x).name() << "(" << x << ")" <<std::endl
int main()
{
    PRINT_TYPE(int);
    PRINT_TYPE(long int);
    PRINT_TYPE(long long int);
    PRINT_TYPE(unsigned int);
    PRINT_TYPE(unsigned long int);
    PRINT_TYPE(unsigned long long int);
    PRINT_VALUE(2147483647);
    PRINT_VALUE(2147483648);
    return 0;
}
int: i
long int: l
long long int: x
unsigned int: j
unsigned long int: m
unsigned long long int: y
2147483647: i(2147483647)
2147483648: m(2147483648)

c++11 だとまた挙動が変わるようです。

int: i
long int: l
long long int: x
unsigned int: j
unsigned long int: m
unsigned long long int: y
2147483647: i(2147483647)
2147483648: x(2147483648)
> 私は-2147483648も-0x80000000もi(int)とみなされると理解していましたが、
> それぞれl(long int)、j(unsigned int)とみなされています。
> そのため-2147483648と-0x80000000を比較しても一致しません(違う値と見なされているため)。

正確な仕様とかは詳しくないので判りませんが、次の通りになっているのだと思われます。

 - `-2147483648` は `2147483648` が long で単項演算子 `-` で `0xFFFFFFFF80000000` → `-2147483648 (long)`
 - `-0x80000000` は `0x80000000` が unsigned int で単項演算子 `-` で `0x80000000` → `2147483648 (unsigned int)`


> 念の為ideoneでも実行してみました:
> http://ideone.com/ErUnhL
> こちらはリテラルがそれぞれm(unsigned long int)、j(unsigned int)のように両方共unsignedと見なされています。

32ビット環境のようなので次の通り・・・

 - `-2147483648` は `2147483648` が unsigned int で単項演算子 `-` で `0x80000000` → `2147483648 (unsigned int)`。
 - `-0x80000000` は `0x80000000` が unsigned int で単項演算子 `-` で `0x80000000` → `2147483648 (unsigned int)`。

と思ったのですが `-2147483648` は `unsigned long` になっていますね・・・

なぜかは判りませんが `2147483648` は `unsigned long` になるようです。

```
#include <iostream>
#include <limits>
#include <typeinfo>
#define PRINT_TYPE(x) std::cout << #x << ": " << typeid(x).name() << std::endl
#define PRINT_VALUE(x) std::cout << #x << ": " << typeid(x).name() << "(" << x << ")" <<std::endl
int main()
{
    PRINT_TYPE(int);
    PRINT_TYPE(long int);
    PRINT_TYPE(long long int);
    PRINT_TYPE(unsigned int);
    PRINT_TYPE(unsigned long int);
    PRINT_TYPE(unsigned long long int);
    PRINT_VALUE(2147483647);
    PRINT_VALUE(2147483648);
    return 0;
}
```

```
int: i
long int: l
long long int: x
unsigned int: j
unsigned long int: m
unsigned long long int: y
2147483647: i(2147483647)
2147483648: m(2147483648)
```

c++11 だとまた挙動が変わるようです。

```
int: i
long int: l
long long int: x
unsigned int: j
unsigned long int: m
unsigned long long int: y
2147483647: i(2147483647)
2147483648: x(2147483648)
```