
No.5ベストアンサー
- 回答日時:
>0除算して、落ちるプログラムと落ちないプログラムが
>あるのですが、何が違いを生んでいるのでしょうか?
「いつ演算しているか?」と「どうやって演算しているか?」により、複雑に違いを生みます。
・いつ演算しているか?
「定数同士の演算式」は、コンパイラの最適化によって「計算済みの定数」に置き換わる場合があります。
そしてそれは「処理系依存」なので「それをするコンパイラもあれば、それをしないコンパイラもある」のです。
で、最適化時に「0除算」と判った時に、どういうコードに最適化されるかも「処理系依存」です。
コンパイラによって「0/0」を「除数が何かチェックせず、0は何で割っても0になるから、0/?はすべて0」に最適化してしまう手抜きなコンパイラもあれば「実行時に0除算を行わせ、0で割ったとの実行時例外を、あえて出すようにしている」と言うコンパイラもあります。
つまり「コンパイラによって、コンパイル時に0にされてしまう場合」と「コンパイル時には計算されず、実行時に計算される場合」があるのです。
そしてそれらは「コンパイルオプション」によって変更出来るので、同じプラットフォーム、同じコンパイル環境でも、指定したオプションやデフォルトオプションが何になっているかで、差が出ます。
・どうやって演算しているか?
int同士の割り算、float同士の割り算、double同士の割り算は、すべて「計算の方法」が異なります。
int同士の割り算は、通常、CPUの「除算命令」で実行します。
前述の最適化による「単なる0にする」と言うのが行われていなければ、例外が発生するでしょう。
そして、デフォルトの例外処理ルーチンを書き変えていないなら、ライブラリのデフォルトの例外処理ルーチンが「Floating point exception」などの表示を行ってプログラムを終了します。
float同士の割り算、double同士の割り算は、通常、浮動小数点演算ライブラリが呼ばれます。
ライブラリでは「浮動小数点演算コプロセッサがあるなら、コプロセッサで計算させ、コプロセッサがないならソフトウェアで演算する」と言う処理をします。
コプロセッサに計算させるCPU命令を実行した場合、0除算の演算結果は「0以外/0は無限大(inf)」になり「0/0は非数(nan)」になります。例外は発生しません。
コプロセッサがなく、ソフトウェアで演算した場合も、0除算の演算結果はコプロセッサがある時と同じです(ソフトウェアで「エミュレート」しているのだから、同じにならなくては困る)
>・intの場合、分子の値によっても落ちるかどうかが変わる。
数学的には「非0÷0=符号付の無限大」「0÷0=未定義(非数、数ではない)」です。
つまり、被除数(分子)が「非0」か「0」かで、結果が変わります。
そして、C言語の仕様では「intでの0除算の結果は、処理系に依存する」事になっています。つまり「何が起こるか判らない」のです。
しかし、floatやdoubleは「無限大」や「非数」をサポートしているので、例外は発生したりしません。
ちゃんと、数学の通りに「非0÷0=符号付の無限大」「0÷0=非数」と言う計算結果になります。
>floatやdoubleはどうやってこの情報(inf, nan)を持っているのかが次の疑問になりました(- -;
IEEE754(IEEE二進化浮動小数点数演算標準)の仕様に従った、浮動小数点の数値は「正負の符号」「指数部」「仮数部」の3つで出来ています。
そして、それぞれ3つの部分の値がどうなっているかで、以下のようになっています。
・符号が0、指数部が0、仮数部が0=正の0
・符号が1、指数部が0、仮数部が0=負の0
・符号が0、指数部が0、仮数部が非0=正の非正規化数
・符号が1、指数部が0、仮数部が非0=負の非正規化数
・符号が0、指数部が0以外かつ最大値以外、仮数部が任意=正の正規化数
・符号が1、指数部が0以外かつ最大値以外、仮数部が任意=負の正規化数
・符号が0、指数部が最大値、仮数部が0=正の無限大(inf)
・符号が1、指数部が最大値、仮数部が0=負の無限大(inf)
・符号が0、指数部が最大値、仮数部が非0=非数(nan)
・符号が1、指数部が最大値、仮数部が非0=非数(nan)
このように「指数部と仮数部の値」によって「無限大」「非数」を表現しています。
あまりに高度すぎてちょっと理解できませんが、状況により結果は変わってくる
ということと捉えました。(かなり大雑把と思いますが。。)
ご回答ありがとうございました。
No.4
- 回答日時:
intel 86系の場合整数でゼロ除算しても SIGFPEが出ますね。
だからこれをつければ落ちない。
signal(SIGFPE, ゼロ除算処理関数のアドレス);
No.3
- 回答日時:
例えば、
#include <stdio.h>
int main()
{
double x = 1.0/0;
printf("%f\n", x);
return 0;
}
といったコードであればxに無限大が格納されますので、プログラムは落ちません。
下記パターンの実験をしました。(gccでコンパイルしましたが、
ccと全ての結果が同じなのかは不明ですが。。)
はじめに自分が落ちると言っていたプログラムはソース2のものでした。
また落ちないと言っていたのはソース6のものでした。
そのため、片方では落ちるし、片方では落ちないとなるようでした。。
この結果からは、
・型によって0除算しても落ちるかどうかが変わる。
→float, doubleはどんな時でも落ちない。
・intの場合、分子の値によっても落ちるかどうかが変わる。
ということが分かりました。(?がついているのはcodepadで実験したので
あまり自信がないという意味です。)
floatやdoubleはどうやってこの情報(inf, nan)を持っているのかが次の疑問に
なりました(- -;
■実験
●ソース1:double, 分子は0でない → inf →落ちない?
●ソース2:int , 分子は0でない → Floating point exception →落ちる?
●ソース3:float , 分子は0でない → inf →落ちない?
●ソース4:double, 分子は0 → nan →落ちない
●ソース5:int , 分子は0 → 0 →落ちない
●ソース6:float , 分子は0 → nan →落ちない
●ソース1:
#include <stdio.h>
int main()
{
double x = 1.0/0;
printf("%f\n", x);
return 0;
}
【実行結果】
inf
●ソース2:
#include <stdio.h>
int main()
{
int x = 1/0;
printf("%d\n", x);
return 0;
}
【実行結果】
Floating point exception
●ソース3:
#include <stdio.h>
int main()
{
float x = 1.0/0;
printf("%f\n", x);
return 0;
}
【実行結果】
inf
●ソース4:
#include <stdio.h>
int main()
{
double x = 0.0/0;
printf("%f\n", x);
return 0;
}
【実行結果】
nan
●ソース5:
#include <stdio.h>
int main()
{
int x = 0/0;
printf("%d\n", x);
return 0;
}
【実行結果】
0
●ソース6:
#include <stdio.h>
int main()
{
float x = 0.0/0;
printf("%f\n", x);
return 0;
}
【実行結果】
nan

No.1
- 回答日時:
0除算して落ちる、落ちないプログラムというのは何を示しているのでしょうか?
・同じソースをコンパイルしても、動作が異なる
・ソースは異なる
coreを吐く、吐かない
動作が止まる、止まらない
0除算にならないように通常は演算の前でチェックを入れるようにします。coreファイルを吐く、吐かないというのであればsignalを受け取って終了処理をしているからcoreファイルを吐かないという事になると思います。
この回答への補足
補足いたします。
ソースは異なります。
一方は動作がとまりますが、
一方は継続します。
coreを吐く吐かないでは
ありません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) プログラムの勉強のおすすめは 7 2022/12/09 20:09
- その他(プログラミング・Web制作) VBA 1 2023/01/19 16:19
- その他(プログラミング・Web制作) FORTRAN77の配列(除算) 2 2023/02/01 14:34
- その他(趣味・アウトドア・車) Arudino nanoが正常に動作しない原因 1 2022/10/30 18:29
- au(KDDI) 昨日 ヤマダ電機でスマホトクするプログラムを使ってauの端末だけ購入しようとしたら分割の審査に落ちま 2 2023/05/06 02:54
- C言語・C++・C# 1. 仮想CPU「exmini」を使用して,「$dataからn減算する」プログラムを作成してください 2 2022/07/04 17:49
- C言語・C++・C# 【CASLプログラム】 定数(80と55)を確保し、その和をGR1に、その差をGR2に求めるCASL 1 2022/12/16 01:17
- ノートパソコン ソフトアンインストール残存ファイル 3 2022/09/13 18:15
- Windows 10 win 10 でのstartup program を削除したい 3 2022/04/29 09:21
- Visual Basic(VBA) VBAが止まります。 2 2022/09/02 14:02
このQ&Aを見た人はこんなQ&Aも見ています
-
見学に行くとしたら【天国】と【地獄】どっち?
みなさんは、一度だけ見学に行けるとしたら【天国】と【地獄】どちらに行きたいですか? 理由も聞きたいです。
-
おすすめの美術館・博物館、教えてください!
美術館・博物館が大好きです。みなさんのおすすめをぜひお聞きしたいです。
-
最強の防寒、あったか術を教えてください!
とっても寒がりなのですが、冬に皆さんがされている最強の防寒、あったか術が知りたいです!
-
あなたなりのストレス発散方法を教えてください!
自分なりのストレス発散方法はありますか?
-
【お題】斜め上を行くスキー場にありがちなこと
運営も客も一流を通り越して斜め上を行くスキー場にありがちなことを教えて下さい。
-
0除算を判定したい
C言語・C++・C#
-
C言語を実行すると-infが出てきて困っています。
C言語・C++・C#
-
関数から配列を返すには?
C言語・C++・C#
-
-
4
C言語 exitの使い方
C言語・C++・C#
-
5
C++言語で、構造体のコピーは可能(しても良い)のでしょうか?
C言語・C++・C#
-
6
0除算の例外処理ができない!!助けて!!
Visual Basic(VBA)
-
7
c++ cmathとmath.h
C言語・C++・C#
-
8
DWORDの実際の型は何でしょうか
C言語・C++・C#
-
9
C言語 配列の長さの上限
C言語・C++・C#
-
10
unsigned long long 型のフォーマット指定子
C言語・C++・C#
-
11
複数の変数を宣言する時、同時に初期化?できないでしょうか?
Java
-
12
IG、ACC、+B、ILL
国産バイク
-
13
<unistd.h>をVisualStudioでつかえるようにする
C言語・C++・C#
-
14
char*を初期化したいのですが
C言語・C++・C#
-
15
CStringのFindで文字列検索を行いたいのですが
C言語・C++・C#
-
16
Enterキーを押されたら次の処理に移るという事をしたい。
C言語・C++・C#
-
17
エディットボックスの入力制限について
C言語・C++・C#
-
18
プログラムでの数字につく”f”の意味
C言語・C++・C#
-
19
配列を使わずに、変数名を動的にループで回したい
C言語・C++・C#
-
20
switch の範囲指定
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・一番好きなみそ汁の具材は?
- ・泣きながら食べたご飯の思い出
- ・「これはヤバかったな」という遅刻エピソード
- ・初めて自分の家と他人の家が違う、と意識した時
- ・いちばん失敗した人決定戦
- ・思い出すきっかけは 音楽?におい?景色?
- ・あなたなりのストレス発散方法を教えてください!
- ・もし10億円当たったら何に使いますか?
- ・何回やってもうまくいかないことは?
- ・今年はじめたいことは?
- ・あなたの人生で一番ピンチに陥った瞬間は?
- ・初めて見た映画を教えてください!
- ・今の日本に期待することはなんですか?
- ・集中するためにやっていること
- ・テレビやラジオに出たことがある人、いますか?
- ・【お題】斜め上を行くスキー場にありがちなこと
- ・人生でいちばんスベッた瞬間
- ・コーピングについて教えてください
- ・あなたの「プチ贅沢」はなんですか?
- ・コンビニでおにぎりを買うときのスタメンはどの具?
- ・おすすめの美術館・博物館、教えてください!
- ・【お題】大変な警告
- ・洋服何着持ってますか?
- ・みんなの【マイ・ベスト積読2024】を教えてください。
- ・「これいらなくない?」という慣習、教えてください
- ・今から楽しみな予定はありますか?
- ・AIツールの活用方法を教えて
- ・最強の防寒、あったか術を教えてください!
- ・歳とったな〜〜と思ったことは?
- ・モテ期を経験した方いらっしゃいますか?
- ・好きな人を振り向かせるためにしたこと
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ABAQUS ユーザーサブルーチン...
-
C++ で、「)」が必要 というエ...
-
Eclipseの環境設定について
-
C++でアボート(Abort)で処理が...
-
0除算して、落ちるプログラムと...
-
sprintfを用いたフォーマット文...
-
変数(関数)名の頭に_
-
不要なインクルードファイルの検出
-
コンパイルできない
-
isnanの取り扱いについて
-
COBOL用のテキストエディタ
-
COBOLのEVALUATE文について
-
__extension__
-
バイナリファイルとソースコー...
-
PC-9801用のフリーな高級言語を...
-
Pythonで、C言語のモジュールを...
-
「.c」拡張子でC++文法を使...
-
PICマイコンによる乱数の表示に...
-
あるプログラムのコマンドライ...
-
VBAで仕様書は書きますか?
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
0除算して、落ちるプログラムと...
-
C++ で、「)」が必要 というエ...
-
C++でアボート(Abort)で処理が...
-
変数(関数)名の頭に_
-
io.hをincludeするとそのような...
-
fortranでのNaNについて
-
ABAQUS ユーザーサブルーチン...
-
Eclipseの環境設定について
-
コンパイルできない
-
Visual C++とVisual C++.NETの違い
-
sprintfを用いたフォーマット文...
-
volatile修飾について
-
関数の戻り値による変数の初期化
-
バイナリファイルとソースコー...
-
C言語のワーニングメッセージの...
-
コンパイラについて
-
FORTRAN→Cに翻訳
-
初心者はIDE使わないほうが良く...
-
どのプログラミング言語ででき...
-
コンパイラフラグ(compiler fla...
おすすめ情報