1

私のルームメイトはちょうど質問を思いついた.

なぜphp(おそらく他の言語も)floor($foo)(int)$foo7なのですか?

$foo = (0.7 + 0.1) * 10;
var_dump(
    $foo,
    floor($foo),
    (int)$foo,
    ceil($foo),
    is_infinite($foo),
    is_finite($foo));

結果

float(8)
float(7)
int(7)
float(8)
bool(false)
bool(true)

$fooは無限数ではないことに注意してください。

回答を見ると、誰もが実際にそうだと言っていることがわかりますx.(9)

しかし、実生活ではあるべき実際の x ではなく、数が存在する理由は何でしょうか?x.(9)

4

4 に答える 4

1

フロア関数は最も近い整数に切り捨てます。int へのキャストは、単に小数部分を捨てるだけです。 $fooは float であり、正確に8 ではない (7.99999 である必要があります...) ため、その動作を観察できます。

于 2013-07-03T17:38:29.583 に答える
1

有理数は、分母に基数の素因数リストに含まれていない素因数が含まれている場合 (つまり、2 と 5) 、繰り返し小数になります。

  • 有理数は、簡約された分数の分母に底の因子ではない素因数が含まれている場合、完全に簡約された分数の分母の値よりも小さい有限の長さの無限に繰り返されるシーケンスを持ちます。簡約分数が基数と素因数を共有している場合、反復シーケンスは基数点の後に有限長のトランジェントが先行します。

https://en.wikipedia.org/wiki/Repeating_decimal

コンピューターの浮動小数点型はほとんど常に 2 進数であるため、有理表現の分母が 2 の累乗でない数値は、無限周期小数になります。たとえば、0.1 はIEEE-754 単精度で0.100000001490116119384765625に丸められます。これは 2 のべき乗の最も近い合計です。

ここでは、0.7 と 0.1 のいずれも 2 進浮動小数点で表現できず、0.8 も表現できません。それらの合計も 0.8 に等しくありません: 印刷0.7 + 0.1 == 0.8を試みると、結果は false になります。実際には0.8よりわずかに小さいです。しかし、それはあなたのような繰り返し小数ではなく7.(9)、小数部分に有限数の 9 を持つ値です。

結果として、ceilandのint結果は 7 になります。or のfloor結果roundを取得すると、8 が得られます。

于 2013-07-27T14:53:22.533 に答える
1

常にではない。浮動小数点の不正確さが原因で 8.0000001 になった場合、フロアは 8 にスナップします。7.999999 になることもあり、7 にスナップします。

0.x を y (ほとんどの言語で int として読み取られる) で乗算している場合、全体が出力されるため、この動作は見られない可能性があります。

これは他の言語でも同様です。

于 2013-07-03T17:37:18.510 に答える