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

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

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

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

554閲覧

c++でオーバーフローが起きる理由がわからない

miagolare

総合スコア6

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2022/04/29 06:45

c++のint型におけるオーバーフローについての質問です。

この問題に対して以下のようなコードを書いたところ、WAと判定されました。

c++

1#include <iostream> 2using namespace std; 3 4int main(){ 5 int N, A[200001]; // Aは商品価格を格納するための配列 6 int B[5]; // Bは価格別の商品の個数を記録する配列 7 cin >> N; 8 for(int i=0; i<N; i++) cin >> A[i]; 9 for(int i=0; i<5; i++) B[i]=0; 10 for(int i=0; i<N; i++){ 11 B[A[i]/100]++; 12 } 13 cout << B[1]*B[4]+B[2]*B[3] << endl; 14}

解答例を確認したところ、「オーバーフロー回避のため64ビット整数を使う」と書いてあったため、 int B[5]の部分を long long B[5]に変えたらACになりました。

問題の制約条件から、配列Bの要素は最大でも200,000にしかならないため、32ビット整数であるint型でもオーバーフローは起きないと考えていました。どうしてこの状況でオーバーフローが起こり得るのか教えていただけると幸いです。

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

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

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

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

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

guest

回答2

0

問題になるのは、以下の部分です。

c++

1 cout << B[1]*B[4]+B[2]*B[3] << endl;

B[1]*B[4」やB[2]*B[3]は、100,000 * 100,000 があり得て、その場合、オーバーフローします。

その為、この部分のキャストだけでも、BAになったと思われます。

投稿2022/04/29 07:10

YT0014

総合スコア1708

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

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

miagolare

2022/04/29 07:16

そっちが問題でしたか! 確かに言われてみればその通りですね。盲点でした。 ご回答ありがとうございました。
guest

0

ベストアンサー

整数の二項演算の結果は原則としてその二項の大きい側の型が結果の型であるというルールです。 (実際にはもっと複雑なルールが色々あります。)

つまりこの場合は B[1]*B[4] という式の型もまた int です。 200000×200000=40000000000 は int (32bit) に収まりませんからオーバーフローになってしまいます。 たぶんこの最後の式だけキャストしても通るんじゃないですかね。

投稿2022/04/29 07:07

SaitoAtsushi

総合スコア5444

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

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

miagolare

2022/04/29 07:17

最後に掛け算をするというのをすっかり忘れていました。 丁寧にご回答いただきありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問