
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で質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
0除算を判定したい
C言語・C++・C#
-
C言語を実行すると-infが出てきて困っています。
C言語・C++・C#
-
0除算の例外処理ができない!!助けて!!
Visual Basic(VBA)
-
-
4
関数から配列を返すには?
C言語・C++・C#
-
5
C言語 exitの使い方
C言語・C++・C#
-
6
1 つのヘッダファイルに複数のクラスって?
C言語・C++・C#
-
7
配列を使わずに、変数名を動的にループで回したい
C言語・C++・C#
-
8
char*を初期化したいのですが
C言語・C++・C#
-
9
DWORDの実際の型は何でしょうか
C言語・C++・C#
-
10
C言語 配列の長さの上限
C言語・C++・C#
-
11
UMLでの例外処理
その他(プログラミング・Web制作)
-
12
正負を反転させて出力するプログラム
C言語・C++・C#
-
13
fopenで別ディレクトリにファイルをオープンしたい
C言語・C++・C#
-
14
構造体のメンバをfor文で回したい
C言語・C++・C#
-
15
<unistd.h>をVisualStudioでつかえるようにする
C言語・C++・C#
-
16
C言語の配列のコピーについて
C言語・C++・C#
-
17
【組込み】割り込み中のstatic変数について。
C言語・C++・C#
-
18
C++言語で、構造体のコピーは可能(しても良い)のでしょうか?
C言語・C++・C#
-
19
unsigned long long 型のフォーマット指定子
C言語・C++・C#
-
20
配列の要素数に変数を入れたいときには
C言語・C++・C#
関連するカテゴリからQ&Aを探す
今、見られている記事はコレ!
-
弁護士が解説!あなたの声を行政に届ける「パブリックコメント」制度のすべて
社会に対する意見や不満、疑問。それを発信する場所は、SNSやブログ、そしてニュースサイトのコメント欄など多岐にわたる。教えて!gooでも「ヤフコメ民について」というタイトルのトピックがあり、この投稿の通り、...
-
弁護士が語る「合法と違法を分けるオンラインカジノのシンプルな線引き」
「お金を賭けたら違法です」ーーこう答えたのは富士見坂法律事務所の井上義之弁護士。オンラインカジノが違法となるかどうかの基準は、このように非常にシンプルである。しかし2025年にはいって、違法賭博事件が相次...
-
釣りと密漁の違いは?知らなかったでは済まされない?事前にできることは?
知らなかったでは済まされないのが法律の世界であるが、全てを知ってから何かをするには少々手間がかかるし、最悪始めることすらできずに終わってしまうこともあり得る。教えてgooでも「釣りと密漁の境目はどこです...
-
カスハラとクレームの違いは?カスハラの法的責任は?企業がとるべき対応は?
東京都が、客からの迷惑行為などを称した「カスタマーハラスメント」、いわゆる「カスハラ」の防止を目的とした条例を、全国で初めて成立させた。条例に罰則はなく、2025年4月1日から施行される。 この動きは自治体...
-
なぜ批判コメントをするの?その心理と向き合い方をカウンセラーにきいた!
今や生活に必要不可欠となったインターネット。手軽に情報を得られるだけでなく、ネットを介したコミュニケーションも一般的となった。それと同時に顕在化しているのが、他者に対する辛らつな意見だ。ネットニュース...
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C++でアボート(Abort)で処理が...
-
C++ で、「)」が必要 というエ...
-
io.hをincludeするとそのような...
-
Delphiの逆コンパイル
-
timeBeginPeriod()関数が使え...
-
0除算して、落ちるプログラムと...
-
プリコンパイラとは?
-
fortranでのNaNについて
-
C言語のワーニングメッセージの...
-
CPUが16bitでも32bitOSでコンパ...
-
コンパイルできない
-
65536は2の何乗なのでしょうか?
-
VBAで仕様書は書きますか?
-
あるプログラムのコマンドライ...
-
正しい五十音順について
-
一番近い組み合わせを見つけるには
-
PICマイコンのコピー(クローン...
-
読み込み中にアクセス違反が発...
-
モジュール、アプリケーション...
-
Bluestacks内でダウンロードし...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C++ で、「)」が必要 というエ...
-
0除算して、落ちるプログラムと...
-
コンパイルできない
-
C++でアボート(Abort)で処理が...
-
io.hをincludeするとそのような...
-
volatile修飾について
-
Delphiの逆コンパイル
-
__extension__
-
Eclipseの環境設定について
-
linuxのセキュリティ対策と致し...
-
プリコンパイラとは?
-
fortranでのNaNについて
-
MFC
-
C言語のワーニングメッセージの...
-
関数の戻り値による変数の初期化
-
コンパイラについて
-
FORTRANとC++の連動について
-
Fortran90を使いたい
-
「.c」拡張子でC++文法を使...
-
PICマイコンによる乱数の表示に...
おすすめ情報