質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

integer

integerは、一般的に整数を表します。プラスやマイナス、ゼロもなりうる全ての数です。(例 : -2, -1, 0, 1, 2...)

Q&A

3回答

6378閲覧

int型でオーバーフローを起こしてしまい1410065408と表示される

vaitarika

総合スコア29

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

integer

integerは、一般的に整数を表します。プラスやマイナス、ゼロもなりうる全ての数です。(例 : -2, -1, 0, 1, 2...)

0グッド

0クリップ

投稿2019/12/06 11:53

C言語で計算結果が100億になるものを扱いたいのですが,表示すると1410065408と表示されてしまいます.表示としてはこうなっていますが,実際に計算に使う分には100億ということになっているのでしょうか.また,これを表示する方法はありますか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

質問者のコンパイラがはっきりしないことと、使ったコードを示していないので、適格なアドバイスができにくい状況ですが、取り急ぎ私のコンパイラ(GCC 5.4.0 x86_64)で実験コードを動かした結果を示します。

C

1#include <stdio.h> 2int main(void) 3{ 4 long int bignum = 0; 5 int billion = 1000000000; // 10億 6 int small = 0; 7 8 for (int i = 0; i < 10; i++) { 9 small += billion; 10 bignum += billion; 11 printf(" %3d: %12ld = %p, %12d = 0x%x, %12d\n", 12 i, bignum, (char*)bignum, (int)bignum, bignum, small); 13 } 14 printf("%d = sizeof(int) \n", sizeof(int)); 15 printf("%d = sizeof(long int)\n", sizeof(long int)); 16 return 0; 17}

コンパイルすると様々 warning (警告)が出ますが、それは置いといて、実行させた結果が次です。

sh

1$ ./a.out 2 0: 1000000000 = 0x3b9aca00, 1000000000 = 0x3b9aca00, 1000000000 3 1: 2000000000 = 0x77359400, 2000000000 = 0x77359400, 2000000000 4 2: 3000000000 = 0xb2d05e00, -1294967296 = 0xb2d05e00, -1294967296 5 3: 4000000000 = 0xee6b2800, -294967296 = 0xee6b2800, -294967296 6 4: 5000000000 = 0x12a05f200, 705032704 = 0x2a05f200, 705032704 7 5: 6000000000 = 0x165a0bc00, 1705032704 = 0x65a0bc00, 1705032704 8 6: 7000000000 = 0x1a13b8600, -1589934592 = 0xa13b8600, -1589934592 9 7: 8000000000 = 0x1dcd65000, -589934592 = 0xdcd65000, -589934592 10 8: 9000000000 = 0x218711a00, 410065408 = 0x18711a00, 410065408 11 9: 10000000000 = 0x2540be400, 1410065408 = 0x540be400, 1410065408 124 = sizeof(int) 138 = sizeof(long int)

普通のCコンパイラは int が 32bit で約±21億まで扱えます。long int は今時のコンパイラだと 64bit だと期待でき、64bit なら100億は余裕で扱えます。
私のコードは 10億(billion変数)を bignum に10回足しこんで100億を目指しつつ、途中経過を複数の表示方法(%12ld, %12d, %x)で表示しています。
同時に int 型の small 変数に足しこんだものも表示してみています。
コードの最後で int と long int のサイズを表示しました。

100億を表示しているのは long int 型変数を %ld 変換指定で表示した場合です。100億は少なくとも34bit必要であることがわかります。
そして、100億のところで 1410065408 が表示されています。この表示は、34bitの数値の、下位32bitを表示したものです。

取り急ぎ、このコードと表示結果を参考にしてみてください。
まずは、long int, long long int など、大きな整数型の sizeof を確認することからやり直したらいかが?その次は printf() の変換指定を調べることかな。

投稿2019/12/06 13:23

編集2019/12/06 13:29
rubato6809

総合スコア1380

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

vaitarika

2019/12/06 13:31

回答ありがとうございます.教えていただいたコードを動かしたところ以下のように出力されました. 0: 1000000000 = 3B9ACA00, 1000000000 = 0x3b9aca00, 1000000000 1: 2000000000 = 77359400, 2000000000 = 0x77359400, 2000000000 2: -1294967296 = B2D05E00, -1294967296 = 0xb2d05e00, -1294967296 3: -294967296 = EE6B2800, -294967296 = 0xee6b2800, -294967296 4: 705032704 = 2A05F200, 705032704 = 0x2a05f200, 705032704 5: 1705032704 = 65A0BC00, 1705032704 = 0x65a0bc00, 1705032704 6: -1589934592 = A13B8600, -1589934592 = 0xa13b8600, -1589934592 7: -589934592 = DCD65000, -589934592 = 0xdcd65000, -589934592 8: 410065408 = 18711A00, 410065408 = 0x18711a00, 410065408 9: 1410065408 = 540BE400, 1410065408 = 0x540be400, 1410065408 4 = sizeof(int) 4 = sizeof(long int) これはどういうことでしょうか。
rubato6809

2019/12/06 13:35

あなたのコンパイラの long int 型は 32bit しかないので 100億を表現できない、ということです。 long int を long long int にするとかして 64 ビットの型があるのであれば、良いのですが、それが無いなら別の手段を使うか、コンパイラを替えるか・・・でしょう。
rubato6809

2019/12/06 13:52

gcc (MinGW.org GCC-6.3.0-1) 6.3.0 ですか。 それは32bit コンパイラかもしれません。long long int 型も32bitかな?だとすると、ひとつの変数で100億を扱うことはできないということ。その場合、多倍長計算などと呼ぶ方法をとります。例えば int 型(=32bit)を2個使って64bitの値を扱うことにすれば100億を表現できるようになるわけだ。。。
guest

0

こちらのように、INT_MAXで最大値が確認できます。
大概の環境では21億程度なので、それ以上の数値を使いたいのであれば、他の型を使う必要があります。

投稿2019/12/06 12:01

fiveHundred

総合スコア9776

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

int型でなくunsigned long long型を使うことで64ビット分の情報を格納できます.
参考

最大で18,446,744,073,709,551,615まで使えるそうです.最大値はULLONG_MAXで表示できます.
参考

投稿2019/12/06 11:56

編集2019/12/06 12:03
dark-eater-kei

総合スコア1248

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fiveHundred

2019/12/06 12:12 編集

念のため勝手に補足を書きますが、以下の説明の通り、C言語の一般的な型の最大値は環境によって変わることがあるのでご注意ください。 > 可変長の整数型は任意の長さとなる。固定長の整数型は、通例処理系の都合によって定義される。従来からあるC言語およびC++の組み込み整数型にはintのほかにshort (short int) とlong (long int) があるが、<limits.h>にて表現可能な上下限値が規定されているだけで、shortの長さはintの長さ以下であればよく、longの長さはintの長さ以上であればよい、という緩い規定しかない(符号なし型も同様)。 (Wikipedia(https://ja.wikipedia.org/wiki/%E6%95%B4%E6%95%B0%E5%9E%8B#%E9%95%B7%E3%81%95)より引用)
vaitarika

2019/12/06 12:15

回答ありがとうございます。使ってみたのですが上手く表示されません。どこか間違えているでしょうか。 unsigned long long a; a=10000000000; printf("%lld\n",a);
fiveHundred

2019/12/06 12:19

「a=10000000000ULL;」とするとどうなりますでしょうか。
dark-eater-kei

2019/12/06 12:25 編集

わたしの環境ではうまく行きました. gcc --version gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0 あと,ideoneでも動作しました. https://ideone.com/k5UIyt コンパイラによっても結果は変わりうるので,原因は断言できません
vaitarika

2019/12/06 12:29

自分の環境は以下の通りでした。 gcc (MinGW.org GCC-6.3.0-1) 6.3.0 バージョンによるものでしょうか。
LouiS0616

2019/12/06 12:50 編集

@fiveHundred さん long longは64bit以上であることは保証されているので、問題無いように思います。
fiveHundred

2019/12/06 12:56

> LouiS0616 さん すいません。そこまで知りませんでした。 失礼しました。
LouiS0616

2019/12/06 13:15

> int _____________at least 16 > long int _________at least 32 > long long int(C99) _at least 64 > Besides the minimal bit counts, the C Standard guarantees that > 1 == sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long). https://en.cppreference.com/w/c/language/arithmetic_types --- とは言えビット数が固定されないのは扱いづらいので、Fixed width integer types というものがC99以降導入されているのですが... 環境に依っては実装されていない型があったり、リテラル表記が無かったり(特に今回のケースでは ll サフィックスに頼るしかなくなんか残念な感じ)、ちょっと使いづらい印象です。 https://en.cppreference.com/w/c/types/integer
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問