簡體   English   中英

C中的雙截斷和數學問題

[英]trouble with double truncation and math in C

我正在制作一個適合球進入盒子的功能。 計算可以放在盒子每一側的球數的代碼如下。 假設球如同立方體一樣裝配在一起。 我知道這不是最佳方式,只是順其自然。

對我來說問題是,雖然我得到了像4.0000000 * 4.0000000 * 2.000000這樣的數字,但是產品是31而不是32.產品是什么?

另外兩件事,這個錯誤只發生在達到最佳邊長時; 例如,邊長為12.2,箱厚為.1,球半徑為1.5。 這導致正好4個球適合那一側。 如果我不把它作為一個int轉換,它可以解決,但如果我作為一個int進行轉換,我得到上述錯誤(31而不是32)。 此外,如果邊長是最佳的,則打印線運行一次,但如果邊長不是,則運行兩次。 我不知道這意味着什么。

double ballsFit(double r, double l, double w, double h, double boxthick)
{
double ballsInL, ballsInW, ballsInH;
int ballsinbox;

ballsInL= (int)((l-(2*boxthick))/(r*2));
ballsInW= (int)((w-(2*boxthick))/(r*2));
ballsInH= (int)((h-(2*boxthick))/(r*2));
ballsinbox=(ballsInL*ballsInW*ballsInH);
printf("LENGTH=%f\nWidth=%f\nHight=%f\nBALLS=%d\n", ballsInL, ballsInW, ballsInH, ballsinbox);
return ballsinbox;
}

基本問題是浮點數學是不精確的。

例如,數字0.1 - 您在有問題的示例中提到的厚度值 - 不能完全表示為double 將0.1分配給變量時,存儲的內容是0.1的近似值

我建議您閱讀科學家應該知道的關於浮點運算的內容

雖然我得到像4.0000000 * 4.0000000 * 2.000000這樣的數字,但產品是31而不是32.產品是怎么回事?

幾乎可以肯定的是,被乘數(至少其中一些)不是它們的樣子。 如果他們都是一模一樣 4.0,4.0和2.0,他們的產品會完全 32.0。 如果你打印出雙打能夠代表的所有數字,我很確定你會看到很多9,如3.99999999999 ......等等。因此,產品有點小於32。 double-to-int轉換只是簡單地刪除小數部分,所以最終得到31。

當然,如果計算精確的話,你並不總是得到比它們更小的數字; 您還可以獲得比您預期的更大的數字。

固定精度浮點數,例如現代計算機中常用的IEEE-754數字,不能准確表示所有十進制數 - 很像1/3無法用十進制精確表示。

例如,當轉換為二進制和返回時, 0.1可以是0.100000000000000004...的行。 差異很小,但很重要。

我偶爾設法(部分地)通過使用擴展或任意精度算法來處理這些問題,以便在計算時保持一定程度的精確度,然后在最終結果中下轉換為double 性能通常會明顯下降,但恕我直言的正確性無限重要。

我最近使用了這里列出的高精度算術庫中的算法,在精度和性能方面都取得了很好的效果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM