4

HTM5番号入力があるサーバー側検証(PHP)を実行しようとしています:

<input ... min="1" max="20" step="0.1" />

ブラウザでは「10.5」などの値を入力できますが、PHP ではこれをどのように二重チェックする必要があるでしょうか。検証を行わないブラウザの場合 (およびブラウザからのデータを信頼してはならないという事実)。

if (fmod(floatval($value), 0.1) == 0) {
    // valid
}

この場合、fmod() は次のように「0.099999...」を返すため、これは機能しません。

異なるプログラミング言語で 0.5 mod 0.1 の結果が異なるのはなぜですか?

$value に 10 を掛けて、(0.1 ではなく) 1 の係数チェックを使用して、整数演算を行うことができます... しかし、ステップが 0.01 または 0.003 の場合はどうなるでしょうか?

4

1 に答える 1

2

数値がフードの下に浮動小数点数として格納される場合、常に最も近い表現可能な数値に丸められます。

値をfloatとして受け入れ、次のようにチェックするだけです。

// get the nearest multiple of $step that is representable in float
$normalized = round($number, $allowed_digits); // for steps like '0.1', '0.01' only
$normalized = round($number / $step) * $step;  // works for any arbitrary step, like 0.2 or 0.3

// verify if they are not too different, where EPSILON is a very small constant
// we cannot directly == as the calculations can introduce minuscule errors
if (abs($normalized - $number) > EPSILON)
   die("Did not validate.");

または、クライアント側からの値を文字列として扱い、文字列で使用されている桁数を確認することもできます(後でfloatに変換します)。ユーザーが0.099999999999ではなく0.01のようなものを入力したことを100%確実にしたい場合は、これを行う必要があります(0.01と同じものに丸められます)。

于 2012-10-15T16:37:38.527 に答える