1

これは文字通り、私が今まで遭遇した中で最も奇妙なものです。というフロートがあり、ratingDecimalいくつかの条件を使用してそれを比較します。条件は次のようになります。

    if (ratingDecimal >= 0.0) {

    if (ratingDecimal < 0.3 && ratingDecimal != 0.3) {

        ratingDecimal = 0.0;

        NSLog(@"bigger or equal to 0 and smaller than 0.3");
    }
}

if (ratingDecimal >= 0.3) {

    if (ratingDecimal < 0.8 && ratingDecimal != 0.8) {

        ratingDecimal = 0.5;

        NSLog(@"middle");
    }
}

if (ratingDecimal >= 0.8) {

    NSLog(@"bigger or equal to 0.8");

    ratingDecimal = 1.0;
}

ここに奇妙な問題があります。を 0.8 に設定しratingDecimalました。コンソールは次のようにログに記録ratingDecimalします。

0.8

しかし、呼び出し:

真ん中

ratingDecimalが 0.3 以上で 0.8 より小さく、0.8 に等しくない場合にのみ呼び出す必要があります。

呼び出される必要があるステートメントは次のとおりです。

if (ratingDecimal >= 0.8) {

NSLog(@"bigger or equal to 0.8"); 

ratingDecimal = 1.0;

}

でも見えない

0.8以上

なぜ私の条件がとても退屈で複雑なのか不思議に思われるかもしれません。

if (ratingDecimal >= 0.3  < 0.8)

彼らは以前はそうでしたが、これがうまくいかなかったので、私は声明を分解し続けましたが、それでも奇妙な振る舞いをしています.

なぜこうなった!?

画像の例を次に示します。

問題

4

3 に答える 3

7

あなたのratingDecimal値はおそらく 0.7999999999999 のようなものです。コンソールに出力されると、おそらく何かが 0.8 に丸められますが、比較ではまだ 0.8 未満と見なされます。

これは、浮動小数点数のバイナリの性質によるものです。これに関する広範な情報については、すべてのコンピューター科学者が浮動小数点演算について知っておくべきことを参照してください。

于 2012-10-15T01:17:01.320 に答える
1

@Greg gave a good answer. I'd like to point out that you can write that code in a much clearer and simpler fashion:

if (ratingDecimal >= 0.0) {
    if (ratingDecimal < 0.3) {
        ratingDecimal = 0.0;

        NSLog(@"bigger or equal to 0 and smaller than 0.3");
    } else if (ratingDecimal < 0.8) {
        ratingDecimal = 0.5;

        NSLog(@"middle");
    } else {
        ratingDecimal = 1.0;

        NSLog(@"bigger or equal to 0.8");
    }
} else {
    // negative
}

As an FYI - a line such as:

if (ratingDecimal < 0.3 && ratingDecimal != 0.3) {

doesn't make such sense. If a number is less than 0.3 then it must be unequal to 0.3 so the second check doesn't do anything useful.

于 2012-10-15T01:38:15.663 に答える
0

必要に応じて roundf() などの関数を使用できます。

于 2012-10-15T08:06:08.113 に答える