- 締切済み
実数型浮動小数点の変数でのゼロ
実数型の変数x,xxについて、以下のようなコードを書きました。 x=0.0 xx=-x write(*,*) x,xx これをコンパイルして実行すると、0.000, -0.000となります。xxにマイナスが付きます。この意味はx=0.0とおいても変数x,xxは実際は0となっておらず微妙に値を持っているからだと思います(無視できるほど小さいとは思いますが)。 これが気になる場合、本当のゼロにすることは可能なのでしょうか。NULLとするとか何かの方法で、ということですが。いちおうFortranなのですが、他の言語では何らかの方法があるかと思いますが。 ひょっとして不可能ということになるでしょうか。
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- f272
- ベストアンサー率46% (8477/18147)
#1です。 「ーがついていると負とみなされる」というのが,どういうことを言っているのかよくわかりませんが, program test double precision :: xd,xxd integer :: i xd = 0.0 xxd = -xd write(*,'(a,g20.15)') " xd=",xd write(*,'(a,g20.15)') "xxd=",xxd if (xd .lt. xxd) write(*,'(a)') " xd < xxd" if (xd .eq. xxd) write(*,'(a)') " xd = xxd" if (xd .gt. xxd) write(*,'(a)') " xd > xxd" if (xd .lt. 0.0) write(*,'(a)') " xd < 0.0" if (xd .eq. 0.0) write(*,'(a)') " xd = 0.0" if (xd .gt. 0.0) write(*,'(a)') " xd > 0.0" if (xxd .lt. 0.0) write(*,'(a)') "xxd < 0.0" if (xxd .eq. 0.0) write(*,'(a)') "xxd = 0.0" if (xxd .gt. 0.0) write(*,'(a)') "xxd > 0.0" if (xd .lt. -0.0) write(*,'(a)') " xd < -0.0" if (xd .eq. -0.0) write(*,'(a)') " xd = -0.0" if (xd .gt. -0.0) write(*,'(a)') " xd > -0.0" if (xxd .lt. -0.0) write(*,'(a)') "xxd < -0.0" if (xxd .eq. -0.0) write(*,'(a)') "xxd = -0.0" if (xxd .gt. -0.0) write(*,'(a)') "xxd > -0.0" END program test を実行すれば xd=0.00000000000000 xxd=-.00000000000000 xd = xxd xd = 0.0 xxd = 0.0 xd = -0.0 xxd = -0.0 となります。
- wormhole
- ベストアンサー率28% (1626/5665)
浮動小数点の仕様を確認してください。 例えばIEEE754での仕様だと https://ja.wikipedia.org/wiki/IEEE_754 符号ビットがあり、その符号ビットで+-を表現するので0でも+0と-0の2つがあることになります。 また、その符号ビットを表示する際にどう扱うのかはまた別の話です。
- superside0
- ベストアンサー率64% (461/711)
コンピュータ上では、bit値の0と1だけで値を保持する関係で 浮動小数点の変数の中身は、実際には表記上の実数値そのものでなく 符号部、指数部、仮数部に分かれて保持しているのはご存知だと思います。 実数値として0であっても、符号を持つということは プラスの0とマイナスの0というのを保持(表現)できることになりますので、 Fortranでは、それをそのまま writeしているだけでしょう。 なお、0.001を1000回加算しても、1にはならずに 1.0001になってしまうという浮動小数点の誤差問題とは別で 指数部も仮数部も0である-0.000..を10億回加算しても-0.000...のままです。 なお、Fortranを含めてプログラム言語としての演算処理では プラスの0とマイナスのセロは イコールと扱うし もともと浮動小数点同士の比較には 誤差を考慮しているでしょうから あまり困ることは ないかと思います。 ちなみに、C言語でも double xd,xxd; int i; xd = 0.0; xxd = -xd; printf ("xd=%G, xxd=%G\n", xd, xxd); printf ("equal=%s\n", xd == xxd ? "true":"false"); for ( i = 0; i < 1073741824 ; i++ ) { xd += xd; xxd += xxd; } printf ("xd=%G, xxd=%G\n", xd, xxd); printf ("equal=%s\n", xd == xxd ? "true":"false"); の結果は xd=0, xxd=-0 equal=true xd=0, xxd=-0 equal=true でした。
- asuncion
- ベストアンサー率33% (2127/6289)
整数型の変数にゼロを入れておいて、 それを浮動小数点数型の変数に入れてみては?
- f272
- ベストアンサー率46% (8477/18147)
> この意味はx=0.0とおいても変数x,xxは実際は0となっておらず微妙に値を持っているからだと思います 違います。0.0と-0.0では数値の内部表現が違うのです。値はどちらも厳密に0に等しいです。 +0.0 = 0 00000000 00000000000000000000000 -0.0 = 1 00000000 00000000000000000000000 参考 https://ja.wikipedia.org/wiki/IEEE_754%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E8%B2%A0%E3%81%AE%E3%82%BC%E3%83%AD#%E8%A4%87%E7%B4%A0%E6%95%B0%E3%81%AA%E3%81%A9
お礼
回答ありがとうございます。この場合、そのあとへの波及も同じでしょうか。例えば、符号を問われた場合の出力値などです。ーがついていると負とみなされるとかですが。