2016-12-30 41 views
0

在我下面的程序,避免垃圾零個值的雙變量

main 
{ 
    // value is 476 
    int value = 476; 

    // here dimension shows as 0.100000001 
    float dimension = 0.1f; 



/// Here I am expecting value as 47.6, 
/// But it gives value as 47.600002288818...... 
double result = value * dimension; 
} 

我想直接保存在數據庫中的值,那麼,有沒有inbuild函數來獲得預期的價值呢?

預期:47.6,而不是47.600002288 .....

+4

如果您想知道爲什麼會發生這種情況:[浮點數學是否被破壞?](http://stackoverflow.com/q/588004/669576)。 –

+3

在任何二進制浮點類型中不存在值「47.6」,只能得到近似值。你的數據庫類型是什麼? – hvd

+0

瞭解每個程序員應該如何將浮點數存儲在內存中。 – DeiDei

回答

3

有幾種方法,但在所有情況下,您都必須弄清楚並確定您的浮點值應代表的精度數。沒有任何關於float的說法,「我實際上是.1而不是0.100000001」。

一旦你決定,說你的值應該帶有兩位數的精度,有幾種方法可以將它們捨去。一種簡單的方法是使用流格式化:

#include <sstream> 
#include <iomanip> 

std::ostringstream o; 

    o << std::setiosflags(std::ios::fixed) << std::setprecision(2) << 0.1; 

std::string s=o.str(); 

您現在將在s中找到「0.10」。

如果您不知道由於您正在進行的任何計算而有多少精度的數字是重要的,您唯一的選擇是使用專用庫進行固定精度算術,like GMP

-1

值存儲47.600002288精密,但是當你要使用它,你可以將浮點後只使用N個數位,例如,如果該值是(47.600002288)在printf使用:

printf("%.2f\n", result); 

這將打印47.60,注意.2%後告訴格式化函數浮點後打印2號。

注意,您可以使用sprintf直接打印到一個字符串:

char s= malloc(sizeof(char)*10); 
sprintf(s, "%.2f\n", result); 
//s contains "47.60" 

在這種情況下,你必須要知道的malloc參數我用sizeof(char)*10這意味着字符長度必須下或等於9(導致最後一個字符保留爲字符串結尾字符\0)。

0

實際上,浮點數是以二進制表示的尾數(基數2)。這樣做的一個結果是0.1十進制(又名1/10)不能用浮點正確表示。

原因與1/3相同,不能完全表示爲固定的小數位數 - 它是無限循環值0.3333333.....,並將其截斷爲有限數量的位置會引入錯誤。唯一的區別是1/10是基數2中的無限循環值。所以它不能完全用有限數量的二進制數字表示。

顯然還有其他值受這種方式影響(如0.20.6等)。這樣的錯誤是浮點表示的固有屬性......或者換句話說,浮點表示一個近似值(可能缺乏精度的值)。而且,當進行一系列計算時,值中的錯誤會傳播。

由於無法精確表示浮點數(以及其他值)中的值0.1,因此無法將浮點值準確存儲到數據庫中,並且得到的值恰好爲0.1

可以嘗試以限制輸出的精度的方式進行打印的值,如

#include <sstream> 
#include <iomanip> 
#include <string> 

std::ostringstream o; 

o << std::fixed << std::setprecision(2) << result; 

std::string s=o.str(); 

請記住這個控制如何result被格式化(例如,在輸出爲一個字符串在這種情況下)。它不會更改result的值。

從理論上講,字符串s可以存儲在您的數據庫....如果該字段表示一個字符串,而不是數字值。