2

for ループで奇妙な問題が発生しています。select_min、select_max、select_step の 3 つの配列キー (実際には選択ボックスを作成しています) に基づいて値を出力する関数に配列を渡しています。ほとんどの場合、それは機能します。最終的にインクリメントされない場合があります。適切に機能しない値もハードコーディングしてみました。

コードは次のとおりです。

for( $a = $property['select_min']; $a <= $property['select_max']; $a += $property['select_step'] ) {
    echo $a . "<br/>";
}

0.1 から 1.2 の「ステップ」でテストしました。特定のインスタンスで機能しない理由がわかりません。小数値のみの問題のようです。

最小: 0、最大: 20、ステップ: 1 - これは機能し、0 ~ 20 を 1 刻みで出力します。

最小: 0.2、最大: 3、ステップ: 0.2 - これは機能せず、0.2 の増分で 0.2 から 2.8 を出力しますが、3 を出力しません。 0から22まで実行すると機能しました。

最小: 0、最大: 7、ステップ: 0.7 - これは機能しません。7 を出力しません。

興味深いケース:

最小: 0、最大: 3、6、または 9、ステップ: 0.3 - 動作

最小: 0、最大: 12 または 15、ステップ: 0.3 - 機能しません

私は他の多くのテストを行ってきましたが、これらの特定のインスタンスで機能しない理由の背後にある共通のスレッドを見つけることができません.

編集:すべての応答に感謝します。私はPetahのソリューションを使用することになり、これを思いつきました:

for( $a = $property['select_min']; 
    bccomp( $a , $property['select_max'] , 1 ) <= 0; 
    $a = bcadd( $a , $property['select_step'] , 1 ) ) {
        $str_editor_html .= '<option value="' . ( !is_float( $property['select_step'] ) ? str_replace( ".0" , "" , $a ) : $a ) . '"' . ( strval( $value['setting'] ) == strval( $a ) ? ' SELECTED' : '' ) . '>' . ( !is_float( $property['select_step'] ) ? str_replace( ".0" , "" , $a ) : $a ) . '</option>';
}

「step」変数に !is_float() のチェックを追加しました。整数の場合は、表示をきれいにするために小数を削除し、末尾のゼロをオフにしています。それを行うためのより直接的な方法があるかもしれませんが、これは完全に機能します。

ありがとうございます!

4

6 に答える 6

3

次のhttp://php.net/manual/en/language.types.float.phpを参照してください。

基本的に、php では float の比較に関して保証はありません。上記のリンクには、問題の説明と代わりに使用できるものを示す赤いボックスがあります。

于 2013-10-01T22:01:30.840 に答える
2

浮動小数点数は 2 進数の 10 進数データとして格納され、常に実数の近似値です。したがって、0.3 を複数回足すと 15 のようになるかもしれませんが、それは 15 ではありません。問題を解決するには、数値に係数 (10 または 100) を掛けて、整数のみを処理します。

于 2013-10-01T22:02:55.317 に答える
1

浮動小数点数は近似値です。バイナリ値は基数 2 を使用するため、1/2、1/4、1/8、... の合計で計算されます。これは、10 進数の 0.2 または 0.3 の有限の正確な値を与えることはできません。したがって、小さな誤差が存在し、同じ値を繰り返し追加してもその誤差が拡大するだけです。

于 2013-10-01T22:01:38.403 に答える
1

他の人が言ったように、それは浮動小数点の精度によるものです。

float のエラーを防ぐために bc math を使用できます。

for ($a = $property['select_min']; 
        bccomp($a, $property['select_max'], 2) <= 0; 
        $a = bcadd($a, $property['select_step'], 2)) {
    echo $a . "<br/>";
}

http://www.php.net/manual/en/ref.bc.php

ここで動作を確認してください: http://codepad.viper-7.com/dBOmGR

于 2013-10-01T22:05:21.560 に答える
0

浮動小数点値は精度が限られているため、2.0 + 0.1 を実行しても正確に 2.1 にはなりません。

これを解決する最も簡単な方法は、整数を使用することです。たとえば、20 から始めて 1 ずつ増やし、値が必要な場合は常に 10 で割ります。

于 2013-10-01T22:02:16.923 に答える
0

すべての値を float にキャストしてみてください。ここには精度の問題があるようです。

または、float のすべての整数表現を使用してみてください。つまり、10 を掛けます (提供した例の場合)。

于 2013-10-01T22:05:44.423 に答える