第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

查找浮點錯誤的現(xiàn)實示例

查找浮點錯誤的現(xiàn)實示例

PHP
犯罪嫌疑人X 2023-09-08 21:46:05
處理金錢和其他精度至關(guān)重要的小數(shù)的通常建議是使用整數(shù)或字符串(加上任意精度庫),如果您了解浮點數(shù)學的工作原理,那么這是有意義的。然而,我手頭沒有任何具體的例子來說明這一點,因為我在野外發(fā)現(xiàn)的每個錯誤計算都是由于其他一些錯誤造成的:使用 進行天真比較,顯示結(jié)果時缺乏適當?shù)纳崛?,公然錯誤的邏輯==(例如,使用不一致的算法計算稅收,該算法在紙上也不起作用)...我做了一些研究,結(jié)果要么僅適用于 C/C++(具有不同精度的浮點/雙精度),要么只是闡述為什么可以不相信兩個浮點數(shù)相等。您能否分享一個獨立的 PHP 代碼片段,其中包含精心挑選的浮點數(shù)字和正確的算法,該算法會呈現(xiàn)由浮點限制明確導致的錯誤結(jié)果?免責聲明:我無意爭論、反駁或揭穿任何東西,老實說我需要一個例子來作為我的工具帶。
查看完整描述

3 回答

?
波斯汪

TA貢獻1811條經(jīng)驗 獲得超4個贊

只要迭代次數(shù)少于十億次,事情就會很容易崩潰。問題是,通過使用浮點數(shù)和算術(shù),您可以很容易地發(fā)現(xiàn)自己得到意想不到的結(jié)果,即使數(shù)字表面看起來不錯,細微的不精確性也可能導致應用程序出錯。


讓我們嘗試一下答案中示例的變體:


$total = 0.0;

for ($i = 0; $i < 10; $i++) {

? ? $total += 0.1;

}


echo "added ten cents, ten times\n";


// since we added 0.1 € x 10 times, we now have 1€ in total, right?

if ($total == 1) {

? ? echo "I have 1€. All is good in the realm.";

}

else {

? ? echo "WTF? Where is my money? I only have {$total}€!!!!\n";

? ? echo "\$total holds: ";

? ? var_dump($total);

}

上述的輸出是:


added ten cents

WTF? Where is my money? I only have 1€!!!!

$total holds: float(1)

即使$total看起來是這樣float(1),代碼也會遵循“錯誤”的執(zhí)行分支,從而破壞了我們的應用程序。


如果我們在 PHP8(目前為測試版)中執(zhí)行相同的代碼,您將得到更容易理解的結(jié)果:


added ten cents

WTF? Where is my money? I only have 1€!!!!

$total holds: float(0.9999999999999999)

另一個簡單的例子:


$balance? ? ? ? ? = 50.03;

$debit? ? ? ? ? ? = 45.42;

$expected_balance = 4.61;

$real_balance? ? ?= $balance - $debit;


if ($real_balance !== $expected_balance) {

? ? echo "problems: ";

? ? var_dump($real_balance);

}

上述的輸出是:


balance mismatch: float(4.61)

或者,在 PHP8 中:


balance mismatch: float(4.609999999999999)

上述兩個例子都表明,實際上,使用浮點數(shù)進行(特別是)貨幣算術(shù)可能會出現(xiàn)問題。由于結(jié)果不再符合您的期望,因此它不僅可能導致明顯錯誤的結(jié)果,而且細微的不同結(jié)果可能使整個應用程序以意想不到的方式運行。



查看完整回答
反對 回復 2023-09-08
?
MYYA

TA貢獻1868條經(jīng)驗 獲得超4個贊

這個問題沒有什么意義,因為這不是浮點錯誤的工作原理。

誤差很小。它們以遠程小數(shù)形式出現(xiàn),只有當您需要非常高的精度水平時它們才會被注意到。畢竟,IEEE 754 為絕大多數(shù)計算機系統(tǒng)提供支持,并且它提供了出色的精度。具體來說,0.1 公里以浮點數(shù)表示為 0.100000001490116119384765625,如果我沒有算錯的話,精確度可達 1/10 μm。

可能沒有一組精心挑選的數(shù)字和現(xiàn)實生活中的計算需要您使用 PHP 進行(發(fā)票、證券交易所指數(shù)...),無論您多么小心地精確,都會呈現(xiàn)不正確的結(jié)果水平。因為那不是問題。

浮點數(shù)學的問題在于,它迫使您在每一步上都非常小心,并且很容易出現(xiàn)錯誤。

對于精度很重要的應用程序,您可以使用浮點數(shù)編寫正確的軟件,但它不會那么簡單、可維護或健壯。


原答案:

這是迄今為止我得到的最好的:

// Set-up and display settings (shouldn't affect internal calculations or final result)

set_time_limit(0);

ini_set('precision', -1);


// Expected accuracy: 2 decimal positions

$total = 0;

for ($i = 0; $i < 1e9; $i++) {

? ? $total += 0.01;

? ? // It's important to NOT round inside the loop, e.g.: $total = round($total + 0.01, 2);

}

var_dump($total, number_format($total, 2));

float(9999999.825158669)

string(12) "9,999,999.83" // Correct value would be "10,000,000.00"

不幸的是,它依賴于大量精度誤差的累積(它需要大約 1,000,000,000 個誤差才會發(fā)生,并且在我的 PC 上運行需要超過 4 分鐘),因此它并不像我想象的那樣真實喜歡,但這確實說明了根本問題。


查看完整回答
反對 回復 2023-09-08
?
不負相思意

TA貢獻1777條經(jīng)驗 獲得超10個贊

echo floor((0.1 + 0.7) * 10);

預期結(jié)果:0.1+0.7=0.8;0.8*10=8;

結(jié)果:7

在 PHP 7.2.12 上測試


查看完整回答
反對 回復 2023-09-08
  • 3 回答
  • 0 關(guān)注
  • 160 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號