タダで使えるBorland C++ Part4

このエントリーをはてなブックマークに追加
356デフォルトの名無しさん
ズバリ聞きますが、


BCCでNaNって使えないの?

double x = 0.0 / 0.0;
if((x) != (x)) {...
やると落ちるし。
printfでは"-NAN"って出るんだけどなぁ...
357デフォルトの名無しさん:05/01/07 00:40:10
>>356
コンピューターは仕組み的に「○○をゼロで割る」ができません。
x!=xも意味わからんし、もっとまともなソースを書いてください。
358356:05/01/07 09:44:28
>>357
まぁまぁ。
ちょいとこいつら見てくだせぇ。

ttp://e-words.jp/w/NaN.html
「0で除算を行なったり、...言語処理系によってはエラーを発生させてプログラムを
中断するが、特殊な数値表現を結果として返し、処理を続行する場合がある。」
0で除算したときに落ちてないから「特殊な数値表現」を返しているんだろうとは思うけど...

あとココの14.9項。
ttp://lagendra.s.kanazawa-u.ac.jp/ogurisu/manuals/c/C-faq/C-faq-14.html
359デフォルトの名無しさん:05/01/08 09:53:02
>>356

IntelのFPUには control word というものがあって、その初期値が
BCとVCとで異なる。BCではゼロ除算で例外を発生するように初期化
されるが、VCではすべての例外はマスクされるために例外が発生し
ない。

BCで数値演算例外を発生しないようにするには、下のソースをコン
パイルして、実行したいプログラムとリンクすればよい。

#include <float.h>
void mask87exceptions(void)
{
_control87(0x1f,0x1f);
}
#pragma startup mask87exceptions

以上。
360デフォルトの名無しさん:05/01/08 10:26:45
>>356
#include <stdio.h>
#include <float.h>

int main(){
  double x = 0.0/0.0;
  if((x) != (x)) {
    printf("NaN(1)\n");
  }
  if(_isnan(x)) {
    printf("NaN(2)\n");
  }
  printf("OK\n");
  return 0;
}

>>359使ってないけど落ちなかった。NaN(2)は表示された。
BCC 5.5.1 + Win2kSP4 にてテスト。
361デフォルトの名無しさん:05/01/08 10:37:35
>>359t
俺も落ちなかったよ。
BCC5.6.4+WinXPSP2
362デフォルトの名無しさん:05/01/08 19:08:35
>>360
ちょっと変えて、下のようにすると落ちる。これを防ぐにはやはり>>359 が不可欠。

#include <stdio.h>
int main() {
double x = 0.0 / 0.0;
if (x != x) printf("NaN != NaN\n");
else if (x == x) printf("NaN == NaN\n");
else printf("both (NaN == NaN) and (NaN != NaN) are false\n");
return 0;
}
363356:05/01/08 20:52:27
おをを、なんか急にたくさんレスが...

>>359
早速試してみたところ、確かに落ちなくなったけど>>360さんの結果と同じく
x != x はfalseになった。まぁ _isnan() があったようなので問題はないと思われます。
それにしても詳しいですなぁ。「control word」なんて聞いたこともなかった。

...isnan()はないかなぁとincludeフォルダ内に検索かけて _isnan() を見つけて
使ってみたけどなんだったか良く覚えてないけどエラーが出てやっぱ使えないかとか
思ってたところで >>360 をコピペしたら動いちゃってあれはなんだったんだとかいう感じです。
今思うとあれは _isnan() の前にあった条件文がいけなかったのかもしれません。

でもとにかく皆さん説明と動作検証本当にありがとうございました。