お口汚しな意見ですみません。ラジアンさんを怒らせちゃったのは私のような...
本当にごめんなさい。
float(4byte)と別な値(例えばint(4byte)(定数もintとみなされる))を計算させると、
まずどっちかかの型に直さないといけないわけで、でもfloatとint、どっちにキャスト
しても値が保証されないので、そういう場合に一時的にDoubleに
変換して計算しておいて、計算したあとで、左辺に代入する時にその型にキャストする、
みたいな事を読んだ記憶があったんです。
だから代入を行っている
ans = ( (A * c.x) + ( pVertex[0].y - ( A * pVertex[0].x ) ) );
ではちゃんとfloatになっているのに、比較を行っている
if(c.y == ( (A * c.x) + ( pVertex[0].y - ( A * pVertex[0].x ) ) ) )
はdoubleのままなので、答えが違っちゃうのかな、と...
それでできなかった理由は、私も知りたいです。
コンパイラのバグということならそれでも納得できます。
でもとりあえずできたから、いいや。
ではなく、原因をぜひとも知りたいです。
PS.私の質問も誰か答えてえ...。(T.T)
doubleで計算してみたら小数点以下7桁以降になんか数値が出てきていました。
どうやらTonnyさんの言う通りのようです。
解決です。
>だから代入を行っている
>ans = ( (A * c.x) + ( pVertex[0].y - ( A * pVertex[0].x ) ) );
>ではちゃんとfloatになっているのに、比較を行っている
>if(c.y == ( (A * c.x) + ( pVertex[0].y - ( A * pVertex[0].x ) ) ) )
>はdoubleのままなので、答えが違っちゃうのかな、と...
なかなかいいところをついているとは思いますが、コンパイラーがどのようなコードを
生成しているかは、実際のコードを見てみなければなりません
----コンパイラーオプションによっても変ってくるからです----
しかし、486 以降の x86 では浮動小数点数の計算はコプロセッサーが担当し、
コプロセッサー内部の精度は 80bit ですから double のままという点には多少の
問題が残ると思います(80bit の方が double よりは少しだけ精度が高いから)
if (c.y == ((A * c.x) +(pVertex[0] - y - (A * pVertex[0].x ))); では
恐らく全てコプロセッサー内での計算をするようなオブジェクトコードを生成する
でしょう(等しいかどうかの判定まで)。そうした場合、float よりははるかに長い
仮数の桁数で計算しますから比較する対象の右の式の方は掛け算や加算や減算やが
入っているので左の c.y の float から 80bit に変換した内部形式ではおそらく
有効な桁数は元の float のままでしょうから、それよりも仮数の有効な値の桁数は
長くも短くもなり得るので、一致しないと判定してもおかしくは無いでしょう
一方、float の変数 ans に代入する際は、仮数の桁数もコプロセッサーの内部形式
から float に変換がおこるので僅(わず)かな違いが見えなくなってしまうのかも
しれません
特定の数値の組み合わせでは、この場合の計算でたまたま一致することがあるのでしょうが
浮動小数点数の場合、等しいかどうかの判定は比較したい数同士が十分近いかどうかで
判定するのが望ましいと私も思います(どの程度なら十分近いかという事が一言で言え
ないので私には尋ねないで下さい)