簡體   English   中英

C ++浮點除法和精度

[英]C++ Float Division and Precision

我知道511除以512實際上等於0.998046875。 我也知道浮子的精度是7位數。 我的問題是,當我用C ++(GCC)進行數學運算時,得到的結果是0.998047,這是一個舍入值。 我更喜歡得到截斷值0.998046,我該怎么做?

  float a = 511.0f;
  float b = 512.0f;
  float c = a / b;

嗯,這是一個問題。 作為float511/512的值是精確的。 沒有舍入。 您可以通過要求超過七位數來檢查:

#include <stdio.h>
int main(int argc, char *argv[])
{
    float x = 511.0f, y = 512.0f;
    printf("%.15f\n", x/y);
    return 0;
}

輸出:

0.998046875000000

float不是十進制數,而是二進制數。 如果將數字除以2的冪,例如512,則結果幾乎總是精確的。 發生了什么是float的精度不僅僅是7位數,它實際上是23 精度。

看看每個計算機科學家應該知道的關於浮點運算的內容

我也知道浮子的精度是7位數。

不是。最常見的浮點格式是二進制格式,精度為24位。 它介於6到7位十進制數字之間,但如果您想了解舍入工作的方式,則無法用十進制表示。

由於b是2的冪,c是完全可表示的。 在十進制表示轉換期間,將發生舍入。 獲取十進制表示的標准方法不提供使用截斷而不是舍入的可能性。 一種方法是要求多一個數字並忽略它。

但請注意,c完全可表示的事實是其值的屬性。 SOme顯然更簡單(如0.1)沒有二進制FP格式的精確表示。

通過某種輸出方法而不是實際存儲的內容,“圓潤”值最有可能顯示出來。 檢查調試器中的實際值。

使用iostream和stdio,您可以指定輸出的精度。 如果指定7位有效數字,將其轉換為字符串,然后在顯示之前截斷字符串,您將獲得輸出而不進行舍入。

想不出你想要這樣做的一個原因,並且考慮到應用程序的后續解釋,你最好使用雙精度,盡管這很可能只是將問題轉移到其他地方。

你的問題並不是獨一無二的,之前已經多次回答。 這不是一個簡單的主題,只是因為發布答案並不一定意味着他們的質量會很好。 如果你瀏覽一下,你會發現真正好的東西。 它會花費你更少的時間。

我敢打賭有人會對我進行評論而不回答。

_____編輯_____

理解浮點的基礎是要意識到一切都以二進制數字顯示。 因為大多數人都難以理解這一點,所以他們試圖從小數位的角度來看待它。

關於511/512的主題,您可以從值1.0開始。 在浮點數,這可以表示為i.000000 ... * 2 ^ 0或隱含位設置(到1)乘以2 ^ 0即等於1.由於511/512小於1,您需要從下一個開始低功率-1給出i.000000 ... * 2 ^ -1即0.5。 請注意,唯一改變的是指數。 如果我們想用二進制表示511,我們得到9個--111111111或浮點與隱式位i.11111111 - 我們可以除以512並將指數放在-1給i.1111111100 ... * 2 ^ -1。

這怎么轉化為0.998046875?

那么從隱式位開始表示0.5(或2 ^ -1),第一個顯式位0.25(2 ^ -2),下一個顯式位0.125(2 ^ -3),0.0625,0.03125等等,直到你' ve代表第九位(第八位顯式)。 總結一下,得到0.998046875。 從i.11111111我們發現這個數字代表精度的9位二進制數字,巧合的是9位小數精度。

如果您將511/512乘以512,您將獲得i1111111100 ...... * 2 ^ 8。 這里有九個精確的二進制數字,但只有三個十進制數字(511)。

考慮i.11111111111111111111111(i + 23個)* 2 ^ -1。 我們將獲得具有24個二進制和24個十進制數字精度的分數(2 ^(24-1)^ /(2 ^ 24))。 給定適當的printf格式,將顯示所有24位十進制數字。 乘以2 ^ 24,你仍然有24個二進制數字的精度,但只有8位小數(16777215)。

現在考慮i.1111100 ... * 2 ^ 2,它出現在7.875。 i11是整數部分,111是分數部分(111/1000或7/8)。 6位二進制數字的精度和4位小數。

做浮點時的思維十進制對於理解它是完全不利的。 釋放自己!

如果您只對該值感興趣,可以使用double,然后將結果乘以10 ^ 6並將其置於最低位置。 再次除以10 ^ 6,您將得到截斷值。

暫無
暫無

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

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