![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
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
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_16.png?e8efa67)
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#
-
0除算の例外処理ができない!!助けて!!
Visual Basic(VBA)
-
doubleの変数にintとintの割り算の結果を代入するとき
C言語・C++・C#
-
-
4
バッファとは何ですか
C言語・C++・C#
-
5
C言語におけるif文の評価順
C言語・C++・C#
-
6
C言語 配列の長さの上限
C言語・C++・C#
-
7
unsigned long long 型のフォーマット指定子
C言語・C++・C#
-
8
数字以外が入力されたらエラー文を出したい。
C言語・C++・C#
-
9
<unistd.h>をVisualStudioでつかえるようにする
C言語・C++・C#
-
10
exeファイルの中身を見ることは可能ですか?
フリーソフト
-
11
C言語のポインタに直接アドレスを割り振りしたい
C言語・C++・C#
-
12
C++のfor文について
C言語・C++・C#
-
13
戻り値を返す関数の前に(void)を付ける
C言語・C++・C#
-
14
ソースコードの1行が長いときの折り返し
PHP
-
15
C言語での引数の省略方法
C言語・C++・C#
-
16
fgetsなどのときのstdinのバッファを消すには?
C言語・C++・C#
-
17
typedef enumの使い方を教えてください
C言語・C++・C#
-
18
char*を初期化したいのですが
C言語・C++・C#
-
19
Excel 16進数
Excel(エクセル)
-
20
fopne で失敗する原因
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
conio.h? curses.h?
-
Visual C++とVisual C++.NETの違い
-
コンパイラフラグ(compiler fla...
-
コンパイラについて
-
0除算して、落ちるプログラムと...
-
65536は2の何乗なのでしょうか?
-
PICマイコンのコピー(クローン...
-
変化させるセルが変化しない
-
Excelで4096点以上のFFTの方法
-
Bluestacks内でダウンロードし...
-
人時生産性をExcelで計算したい
-
パソコン
-
自動クエリとはどういうもので...
-
万年暦を導き出すプログラミング
-
未使用の変数を一括検索する方法
-
「ルーチン」という言葉の意味
-
乗換案内の作り方が知りたいです。
-
スクリーンセーバーの作り方
-
VBからシャットダウンさせる方法
-
バッチファイルでウインドウを...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
0除算して、落ちるプログラムと...
-
CPUが16bitでも32bitOSでコンパ...
-
C++ で、「)」が必要 というエ...
-
C++でアボート(Abort)で処理が...
-
コンパイルできない
-
io.hをincludeするとそのような...
-
変数(関数)名の頭に_
-
コンパイラについて
-
fortranでのNaNについて
-
ABAQUS ユーザーサブルーチン...
-
volatile修飾について
-
Visual C++とVisual C++.NETの違い
-
コンパイラの制限 : ヒープの領...
-
Eclipseの環境設定について
-
graph.hがincludeできない
-
Delphiの逆コンパイル
-
プリコンパイラとは?
-
sprintfを用いたフォーマット文...
-
PICマイコンによる乱数の表示に...
-
C++の Unhandled Exceptionにつ...
おすすめ情報