えムナウ Blog

えムナウ の なすがまま

目次

Blog 利用状況

ニュース


follow mnow at http://twitter.com


えムナウのプログラミングのページ

INETAJ

書庫

日記カテゴリ

ギャラリ

びっくりした事

以下のコンソールアプリケーションで"NG"と表示するケースがあった。


class Program
{
 static void Main(string[] args)
 {
  double d1 = ある計算式;
  double d2 = d1;
  Check(d1, d2);
 }
 private static void Check(double d1, double d2)
 {
  if (d1 == d2)
  {
   Console.WriteLine("OK");
  }
  else
  {
   Console.WriteLine("NG");
  }
 }
}

非常にびっくりしたのでクイズにします。
ある計算式とは何でしょう?
一番簡単(文字数が少なく)に書いてみて!

投稿日時 : 2009年10月14日 14:10

コメントを追加

# re: びっくりした事 2009/10/14 16:08 774RR

静かに「何ですか」

# re: びっくりした事 2009/10/14 17:40 えムナウ

通常は d2 = d1; で代入しているのでd1,d2は同じものです。
したがってCheck()ではOKがでます。
ある計算式(空白抜きで4文字)を書くとコンパイルエラーにならず実行時にNGがでるのです。

# re: びっくりした事 2009/10/14 18:20 774RR

いやもう答え書いたつもりなんですが・・・

# re: びっくりした事 2009/10/14 19:19 えムナウ

そこまで読めなかった。w
ほぼあっていますが。

計算式なんです。
空白抜きで4文字です。

# re: びっくりした事 2009/10/14 19:40 irxn

IEEEk規格の数でない部分(NaNなど)なら比較で必ずfalseが出るのでは無いでしょうか。
やってないけど 1/0はどうですか?

# re: びっくりした事 2009/10/14 19:41 irxn

って、一つ目のコメントをスルーしてた。ごめんなさい

# re: びっくりした事 2009/10/14 19:51 まりも

答えを書いていいのかな?

.0/0
ですね。
長く書いていいなら、
double.NaN

そういえば昔数学で習ったような気がしてきました。
ここまで実装してあるとはよく考えてありますね。



# re: びっくりした事 2009/10/14 20:01 zecl

ぱっと見だとNGになるパターンは思い浮かばないかもですね。

どうでもいい別解を・・。
0D/0

# re: びっくりした事 2009/10/14 20:38 えムナウ

1/0 はNGです。
0/0 はコンパイルエラー。

.0/0
0D/0
正解です。

4文字で8パターンあるんですよ。

# re: びっくりした事 2009/10/15 7:20 bleis-tift

8パターン・・・
.0/0 0./0 0/.0 0/0. 0D/0 0d/0 0/0D 0/0d
かな。試してませんが。

# re: びっくりした事 2009/10/15 13:54 刈歩 菜良 CTP

答えを聞いてもわからな~い!
解説ぷり~ず

# re: びっくりした事 2009/10/15 14:44 えムナウ

VisualStudio2008 で 8パターン は以下の通りです。
0/.0 と 0/0d と 0/0f と 0/0e
.0/0 と 0d/0 と 0f/0 と 0e/0

0./0 はコンパイルエラーです。

もちろん、大文字小文字を別解にするとあと6パターン増えます。

本来の意図とは違いますが / を % に変えても成り立ちます。
それを考えると16パターン、大文字を別解とすると 28パターンです。

# re: びっくりした事 2009/10/15 14:51 えムナウ

double.NaN は 0を0で割った本来は割れないとされる非数(数でないもの)です。
数でないので比較は全て一致しないことになります。

したがって、NaN != NaN なので、double で同じもののはずなのに比較すると等しくないことになります。

# re: びっくりした事 2009/10/15 20:53 774RR

NaN (Not a Number) は結果が無い(存在しない)演算の結果として得られるので
0/0 や sqrt(-1.0) や log(-1.0) の結果は NaN です。
Infinity/-Infinity とは違うので要注意かもしれません。
たとえば log(0.0) は -Infinity です。

NaN は他のどの数値とも同値にならない (NaN 同士でも) という決まりになっています。

これらは IEEE 754 で決められています。
本来 IEC 559 が採択済みなのに IEEE 754 を使うというのも筋違いなのですが。

で NaN にも複数種類があって、少なくとも
signaling_NaN と silent_NaN の2つが規定されています。
静かな 何? としゃれてみたつもりだったのですが。

# re: びっくりした事 2009/10/17 0:59 zecl

大変こまかいツッコミで恐縮ですが、
127パターンは確認しました。


除算演算子
http://msdn.microsoft.com/ja-jp/library/aa691373(VS.71).aspx

剰余演算子
http://msdn.microsoft.com/ja-jp/library/aa691374(VS.71).aspx

# re: びっくりした事 2009/10/17 9:19 えムナウ

>127パターンは確認しました。
4文字でですか?

4文字以外ではかなりの量あると思います。
-1のルートなんかもそうですしね。

# re: びっくりした事 2009/10/17 10:17 zecl

もちろん4文字でです。
自分も間違えないように覚書としてブログで記事にしました。

http://bit.ly/Qfkt3

# re: びっくりした事 2009/10/17 11:24 お だ

はじめまして。お だです。
おもしろそうだったので、参考にさせてもらいました。

Groovy って NaN の比較が Java と違う…
http://d.hatena.ne.jp/odashinsuke/20091017/1255745640

# re: びっくりした事 2009/10/18 9:21 えムナウ

なるほど、剰余の場合は分子が0である必要はないのですね。

# re: びっくりした事 2009/10/19 22:36 刈歩 菜良 CTP

解説ありがとうございます。

doubleだとDivideByZeroExceptionみたいなエラーにならないんですねぇ。
数学的にはどうあれ、ビジネスロジック的にはエラーにしてもらったほうが楽なような気が...

# re: びっくりした事 2012/03/31 0:19 とおりすがり

x86CPUのFPUは浮動小数点のゼロ除算をエラーに設定可能で、NT系OSのVCとかならトラップできたはずです。
DotNetだと無理なんですね・・・知らなかったヨ

# re: びっくりした事 2012/03/31 0:19 とおりすがり

x86CPUのFPUは浮動小数点のゼロ除算をエラーに設定可能で、NT系OSのVCとかならトラップできたはずです。
DotNetだと無理なんですね・・・知らなかったヨ

# RaNebEBIYjtGbmtny 2021/07/03 5:03 https://www.blogger.com/profile/060647091882378654

This is one awesome article post.Really looking forward to read more. Much obliged.

# http://perfecthealthus.com 2021/12/22 19:07 Dennistroub

Whatв??s up, I would like to subscribe for this blog to get most up-to-date updates, so where can i do it please assist.

タイトル  
名前  
URL
コメント