🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C++11

C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

C

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

C++

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

Q&A

解決済

3回答

5339閲覧

C++で計算結果が10の18乗を超えた時という条件を実装したい

YUMA-NAGAO

総合スコア41

C++11

C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

C

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

C++

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

0グッド

0クリップ

投稿2021/03/03 02:56

#前提・実現したいこと
競技プログラミング初心者です。
Pythonからプログラミングを始め、C++を今回始めて触っています。

AtCoderのB - Multiplication2 を解こうとしています。
値の大きさより、intではなくlong longを使ったコードを作成しました。
しかし、long longでも10の19乗を超える値は、オーバーフローしてしまいます。

#試したこと
こちらのサイトに書かれてい解決策を参考に、値に解決しようとしました。
しかし、2つ目のifに書かれている-1が出力されてしまいます。

#発生している問題・エラーメッセージ
計算結果がオーバーフローしてしまって、値がうまく出力されない。

#該当のコード

C++

1#include <iostream> 2using namespace std; 3int main(void){ 4 // Your code here! 5 int N; cin>>N; 6 int ans=1; 7 for (int i=0;i<N;i++){ 8 int num; cin>>num; 9 if (num==0) { 10 cout<<"0"<<endl; 11 exit(0); 12 } 13 14 if (ans<=1e18/num){ 15 cout<<"-1"<<endl; 16 exit(0); 17 } 18 19 ans*=num; 20 } 21 cout<<ans<<endl; 22} 23

#教えていただきたいこと
2点あります。

1、どのようにコードを変えればいのか?
3、解決方法の導き方

自力で解決できるようになりたいので!

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

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

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

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

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

kazuma-s

2021/03/03 17:59

> 値の大きさより、intではなくlong longを使ったコードを作成しました。 質問のコードには long long が使われていません。 作成したコードに変更してください。
guest

回答3

0

ベストアンサー

以下を直せば動きました。

  • ansとnumはlong longにする。(intだと2^31-1が上限なので、計算中にオーバフローしている)
  • if(ans > 1e18/num)に直す。(他の方の丁寧な回答を参照してください)
  • 1e18を1000000000000000000に直す。

 これは自分の予想が含まれるのですが1e18はdouble型になるため、1e18/numもdouble型になっている。double型の有効桁数が10進数で15桁程度なので、1e18/999999000001の計算結果が1000000.999999999998999999ではなく1000001.00000に丸められてしまう。その結果-1のルートに入らない。)

投稿2021/03/22 13:40

編集2021/03/22 13:41
hagi3to5

総合スコア23

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

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

YUMA-NAGAO

2021/03/22 21:56

教えていただきありがとうございます!
guest

0

__int64型だと値の範囲は-9223372036854775808~9223372036854775807
です。
これだとオーバーフローしないと思いますが。

投稿2021/03/09 08:33

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

問題文を見るに,結果が10^18を超える場合は-1を出力せよ,とのこと.
素直に考えれば,
if( 計算中の値 >= 1e18 ){ -1を出力 }
という形になるのでは?

ansnumを乗じたら10^18以上になるかどうかをチェックするならば,
その条件式とはans * num >= 1e18という形でしょう.
これを単純に書いたならば,
if( ans >= 1e18/num ){ -1を出力 }
となるのではないでしょうか.

投稿2021/03/03 03:06

fana

総合スコア11990

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

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

YUMA-NAGAO

2021/03/03 03:25

if( ans >= 1e18/num ){ -1を出力 } をすると、long longで定義できる範囲の価を超えてしまうので、それ以外の方法で、やろうとしています…。 c++で、10の18乗などの大きな値を保持できる型などがありましたら、教えていただきたいです
ozwk

2021/03/03 03:37

「超える」なので ans>1e18/num ですね。
fana

2021/03/03 03:58 編集

とりあえず理屈の上で, > if (ans<=1e18/num) では 不等号の向きが違うのではないか? ということを述べたつもり. > 2つ目のifに書かれている-1が出力されてしまいます。 という事柄の原因として.
Zuishin

2021/03/03 04:02

大きい数で考えると難しいですね。9 を超えたら -1 というルールで考えてみましょう。 5 に 2 をかけると 9 を超えるかどうかは、5 > 9 / 2 が true になることで調べられます。5 > 4.5 なので 5 × 2 は 9 を超えます。 ただし 4.5 という小数が使えない場合はもう一工夫必要です。 9 + 1 を 2 で割ってみましょう。かけられる数がそれ以上であれば 10 以上になる、つまり 9 を超えることになります。5 >= (9 + 1) / 2 なので、5 に 2 をかけると 10 以上になることがわかります。 unsigned long long なら 10 の 19 乗を保持できるので同じように計算できるのではないでしょうか。
Zuishin

2021/03/22 09:08

でしょうね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問