

C++において、int型とlong型とlong long型の違いについて教えていただきたいです。  
特に表現できる上限値について知りたくて、調べてみると下記な認識です。

int -> 2^31 - 1  
long -> 2^31 - 1  
long long -> 2^63 - 1

intとlong longの違いはわかるのですが、longの位置付けがよくわからないです。  
longもlong longも2^63 - 1ですし。Atcoderの解説の動画で、intで足りない場合はlong
longを使うといった内容を解説されたのですが、え、intの次っていったらlongじゃないのかな？  
などと疑問に思って調べてみたらなおさらよくわからなくなったという背景です。

longとlong longの違いについて、上限値の観点で説明いただけますと助かります。  
バージョンによるかもしれないので、c++11使ってることも共有しておきます。

よろしくおねがいします。


CC BY-SA 4.0
2018-07-12T00:23:35.913
45529
2018-07-13T00:13:51.827
29267
question
c++ c++11
C++言語でのint型とlong型とlong long型の違いについて


int型とlong型とlong long型は、limits.h で定義されていますので、お使いのC++コンパイラのヘッダファイルを確認してください。  
特殊な整数型が "stdint.h" で定義されている場合もあるので、念のため確認してください。

int型とlong型とlong long型の違いは、計算機環境(CPUのビット数）に依存します。  
int型はCPUのビット数と同じビット数の整数、longは32ビットの整数、long
longは64ビットの整数となっている場合が多いように思います。("整数"との表記は、整数と符号なし整数の両方を含むものという意味で使っています。)  
表にすると、CPUの種類（ビット数）と、それぞれのint,long, long longのビット数は以下のような感じ。

>
[code]

>                   int      long      long long
>       16bit CPU    16        32             64
>       32bit CPU    32        32             64
>       64bit CPU    64        64             64
>  
[/code]


CC BY-SA 4.0
2018-07-12T01:23:26.047
45531
2018-07-12T01:23:26.047
217
45529
answer


[c](/questions/tagged/c "'c' のタグが付いた質問を表示") は太古からある言語です。
[c++](/questions/tagged/c%2b%2b "'c++' のタグが付いた質問を表示") は
[c](/questions/tagged/c "'c' のタグが付いた質問を表示") との互換性を重要視している言語なので、この件に関しては事情は
[c](/questions/tagged/c "'c' のタグが付いた質問を表示") と同じです。というあたりを知ってもらった上で

[c](/questions/tagged/c "'c' のタグが付いた質問を表示") は 8bit マイコンでも 16bit
マイコンでも使える言語です。そして `int` は「その処理系で自然な大きさ」を選べるよう、言語規格書上は大きさ（ビット数）を厳密に定めていません。

[c99](/questions/tagged/c99 "'c99' のタグが付いた質問を表示") 言語規格書 ISO/IEC 9899:1999
が定めているのは

  * `char` は 8bit 以上 `int` 以下のサイズであること
  * `int` は 16bit 以上のサイズであること
  * `long` は 32bit 以上 `long long` 以下のサイズであること
  * `long long` は 64bit 以上のサイズであること

今でも組み込み系で当然のように使っている 8/16bit マイコンで先の条件を満たすには

  * `char` 8bit
  * `int` 16bit
  * `long` 32bit

32bit マイコンあるいは x86 等の高級 32bit プロセッサでは同様

  * `char` 8bit
  * `short` 16bit
  * `int` 32bit

では `long` や `long long` を具体的にどの大きさにするかはプロセッサ自体の設計者やコンパイラの設計者や OS
自体の仕様策定者の判断にゆだねられるところです。この判断の基準には

  * よりハードウエアの性能を引き出しやすい (32bit 専用ソースを書きたい)
  * より既存のソフトウエアを移植しやすい (16bit 時代のソースに手を入れたくない）

という相反する面があって、紆余曲折の末、多くの 32bit プロセッサ用コンパイラでは

  * `long` 32bit (16bit 時代のソースコードとの互換性確保のため)
  * `long long` 64bit (`long` より大きい型が必要になったため)

に落ち着いています（ご質問の中に書かれているとおり）。

なのでご質問に対する回答は「昔のソースコードを移植しやすい型サイズを選んだ結果、このサイズが採用されている」となるでしょう。

64bit プロセッサの場合は「既存のソフトウエアとの互換」面が特に重要視されており、型の大きさに関しては異なる仕様が並存しているのが現状です。 LP64
とか LLP64 とか。  
<https://project-
flora.net/2015/07/21/cc%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E6%95%B4%E6%95%B0%E5%9E%8B%E3%81%AB%E3%81%AF%E6%B0%97%E3%82%92%E3%81%A4%E3%81%91%E3%82%88/>

そして型の大きさがコンパイラによって異なるのはすごく不便と言うことで [c99](/questions/tagged/c99 "'c99'
のタグが付いた質問を表示") や [c++11](/questions/tagged/c%2b%2b11 "'c++11' のタグが付いた質問を表示")
では大きさを厳密に定めた型とかが追加されています（上記ページでも解説されています）。移植性を重視するなど型の大きさを気にする必要がある場合は `int` や
`long` といった処理系ごとに大きさが違う可能性のある型を使わずに `int16_t` などを使うことが推奨されています。


CC BY-SA 4.0
2018-07-12T01:36:17.320
45532
2018-07-12T05:45:01.627
2018-07-12T05:45:01.627
8589
8589
45529
answer


C/C++の各整数型が持つ上限値（ビット幅）というのはシステムによって異なります。（もちろん、システムごとに`sizeof(int) <=
sizeof(long) <= sizeof(long long)`は常に成立）

[基本的な型 -
cppreference.com](https://ja.cppreference.com/w/cpp/language/types)によれば、具体的には

  * `int` 16ビットもしくは32ビット
  * `long` 32ビットもしくは64ビット
  * `long long` 64ビット

の幅を持つ可能性があります。従って、`long`は常に`int`より大きいとは限らないということが分かります。一方`long
long`は64ビット幅を持つことが保証されているので、必ず`int`より大きく「intで足りない場合はlong
longを使う」という方針が常に有効であることが分かります。

少なくともAtCoderに関する限りは、`int`=32ビット, `long
long`=64ビットと考えて差し支えないと思います。もし心配なら`int32_t`や`int64_t`のようなビット幅を明示した型を使うとよいでしょう。

ところでAtCoderはGCCが使われていますが、GCCでは[`__int128`](https://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html)という128ビット幅を持つ整数が定義されており、64ビットでも不足する場合に対応することができます。


CC BY-SA 4.0
2018-07-12T02:36:45.260
45535
2018-07-12T02:36:45.260
13199
45529
answer


みなさんが回答されているようにC言語およびC++言語では`int`、`long`、`long long`のサイズは指定されておらず実装依存です。

例えば[Visual C++およびWindows](https://docs.microsoft.com/ja-
jp/cpp/cpp/fundamental-types-cpp#sizes-of-fundamental-types)では

> `int` 32bit  
>  `long` 32bit  
>  `long long` 64bit

と定められています。  
AtCorderについてググって見つけた範囲では[Language Test](https://language-
test-201603.contest.atcoder.jp/)のページに

> 注意：AtCoderのジャッジサーバーに関する情報は以下を参照してください
[code]

>     $ uname -a
>     Linux ip-***-***-***-*** 3.13.0-74-generic #118-Ubuntu SMP Thu Dec 17
> 22:52:10 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
>     $ cat /etc/lsb-release
>     DISTRIB_ID=Ubuntu
>     DISTRIB_RELEASE=14.04
>     DISTRIB_CODENAME=trusty
>     DISTRIB_DESCRIPTION="Ubuntu 14.04.4 LTS"
>  
[/code]

とありLinux x86_64を使用しているようです。Linuxでは[Linux Standard
Base](http://refspecs.linuxfoundation.org/lsb.shtml)が定められていて[Linux Standard
Base Core Specification for X86-64 / Chapter 7. Low Level System Information /
7.1. Machine Interface / 7.1.2. Data Representation / 7.1.2.3. Fundamental
Types](http://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-AMD64/LSB-Core-
AMD64/lowlevel.html#FUNDAMENTALTYES)では

> LSB-conforming applications shall use only the fundamental types described
> in Section 3.1.2 of System V Application Binary Interface AMD64 Architecture
> Processor Supplement.

と定められており、[System V Application Binary Interface AMD64 Architecture Processor
Supplement / Chapter 3 Low Level System Information / 3.1.2 Data
Representation / Fundamental Types](http://refspecs.linux-
foundation.org/elf/x86_64-abi-0.95.pdf#page=13)では

> `int` 32bit  
>  `long` 64bit  
>  `long long` 64bit

と定められています。同様に調べるとわかりますがLinux
x86では`long`が32bitと定められているため、`long`はx86とx86_64とでサイズが異なります。


CC BY-SA 4.0
2018-07-13T00:13:51.827
45566
2018-07-13T00:13:51.827
4236
45529
answer