2008-11-20 61 views

回答

5

首先知道浮點數是近似值是很重要的。請參閱@Greg Hewgill提供的鏈接,瞭解爲什麼此問題無法完全解決。

但這裏有一對夫婦的解決問題的辦法,可能會滿足你的需要:

可能是更好的方法,但效率較低:

char sz[64]; 
double lf = 0.600000002; 
sprintf(sz, "%.4lf\n", lf); //sz contains 0.6000 

double lf2 = atof(sz); 

//lf == 0.600000002; 
//lf2 == 0.6000 

printf("%.4lf", lf2); //print 0.6000 

的更有效的方法,但可能不太精確:

double lf = 0.600000002; 
int iSigned = lf > 0? 1: -1; 
unsigned int uiTemp = (lf*pow(10, 4)) * iSigned; //Note I'm using unsigned int so that I can increase the precision of the truncate 
lf = (((double)uiTemp)/pow(10,4) * iSigned); 
6

實際上這是不可能的。這不是C++的限制,而只是浮點運算的方式。對於許多值沒有精確的表示,所以你不能簡單地截斷爲一些數字。

使用printf格式字符串打印時,可能會截斷。

如果您確實需要只能存儲有限數量的數字,我建議您改用固定精度的數據類型。

3

我認爲這裏應該問的問題是: 爲什麼你需要它被截斷?

如果它用於比較值之間,也許你應該考慮使用epsilon測試。 (在你的情況下,額外的容差值,因爲它似乎遠遠大於普遍接受的epsilon)。

如果您只是想將其打印爲0.6000,請使用他人建議的方法。

1
roundf(myfloat * powf(10, numDigits))/powf(10, numDigits); 

例如,在你的情況下,你截斷三個數字(numDigits)。你會使用:

roundf(0.6000002 * 1000)/1000 
// And thus: 
roundf(600.0002)/1000 
600/1000 
0.6 

(你可能會存儲函數powf結果的地方,因爲你使用它的兩倍。)

由於如何花車通常儲存在電腦裏,有會可能是不準確的。不過,這就是你使用浮動的原因。

1

使用此:

floor(0.6000002*10000)/10000 
0

下面是使用在其他的答案的建議和其使用的一個例子的功能:

#include <iostream> 
#include <cmath> 

static void Truncate(double& d, unsigned int numberOfDecimalsToKeep); 

int main(int, char*[]) 
{ 

    double a = 1.23456789; 
    unsigned int numDigits = 3; 

    std::cout << a << std::endl; 

    Truncate(a,3); 

    std::cout << a << std::endl; 

    return 0; 
} 

void Truncate(double& d, unsigned int numberOfDecimalsToKeep) 
{ 
    d = roundf(d * powf(10, numberOfDecimalsToKeep))/powf(10, numberOfDecimalsToKeep); 
} 
0

到其他的答案相似,但你一定不要忘記圓,floor和trunc根據定義不同。請參見下面的定義和輸出例如:

http://www.cplusplus.com/reference/cmath/trunc/

在這種情況下,我們需要用4位小數精確到trucate,擺脫非顯著小數的:

trunc(valueToTrunc*10000)/10000 

value = (double)((int)(valueToTrunc*10000))/(double)10000 
0

對於C++ 11可以使用在標題<cmath>定義std::round

auto trunc_value = std::round(value_to_trunc * 10000)/10000;