2

私はプログラムの例を持っています:

int main()
{
    double x;
    x=-0.000000;
    if(x<0)
    {
        printf("x is less");
    }
    else 
    {
        printf("x is greater");
    }
}

コントロールが最初のステートメントで行われるのはなぜですか - x is less . -0.000000 とは?

4

3 に答える 3

9

IEEE 754 は、非常に一般的に使用される標準の浮動小数点数を定義します。ここでその構造を見ることができます:

底が 2 (2 進数) または底が 10 (10 進数) の有限数。各有限数は 3 つの整数で表されます: s = 符号 (ゼロまたは 1)、c = 仮数 (または「係数」)、q = 指数。有限数の数値は

  (−1)^s × c × bq

ここで、b は基数 (2 または 10) です。たとえば、符号が 1 (負を示す)、仮数が 12345、指数が -3、基数が 10 の場合、数値の値は -12.345 です。

ダブルFP数

したがって、分数が 0 で符号が 0 の場合、+0.0 になります。
分数が 0 で符号が 1 の場合、-0.0 になります。

数字は同じ値ですが、正負のチェックが異なります。これは、たとえば、次の場合を意味します。

x = +0.0;
y = -0.0;

次に、次のように表示されます。

(x -y) == 0

ただし、x の場合、OP のコードは「x が大きい」となりますが、y の場合は「x が小さい」となります。

編集: Artur回答とこの回答に対するJeffrey Saxのコメントx < 0は、OP の質問のテストの違いは実際にはコンパイラの最適化であり、実際にはx < 0ポジティブとネガティブの両方のテスト0は常にfalse.

于 2013-11-12T06:35:19.537 に答える
1

負のゼロはまだゼ​​ロであるため、+0 == -0 および -0 < +0 は false です。これらは同じ値の 2 つの表現です。それが違いを生む操作はほんのわずかです。

  1. 1 / -0 = -無限大、1 / +0 = +無限大。
  2. sqrt(-0) = -0、sqrt(+0) = +0

負のゼロは、いくつかの異なる方法で作成できます。

  1. 正の数を -infinity で割るか、負の数を +infinity で割る。
  2. 負の数でアンダーフローを生成する演算。

これはかなりあいまいに思えるかもしれませんが、これには十分な理由があり、主に複素数を含む数式を一貫させることに関係しています。たとえば、1/√(-z)==-1/√z上で行ったように平方根を定義しない限り、ID は正しくないことに注意してください。

詳細を知りたい場合は、William Kahan の Branch Cuts for Complex Elementary Functions か、The State of the Art in Numerical Analysis (1987) の Much Ado About Nothing's Sign Bit を探してみください

于 2013-11-12T06:42:07.403 に答える