2017-09-02 46 views
0

所以我想寫一個代碼,它可以讓我將任意數字舍入到小數點後3位。我對圍捕一個數字代碼是這樣的:C中的舍入函數

for (rowIndex = 0; rowIndex < MAX_ROWS; rowIndex++) 
{ 
    for (columnIndex = 0; columnIndex < MAX_COLUMNS; columnIndex++) 
    { 
     printf("%.3f ", ceil(rawData[rowIndex][columnIndex] * 1000.0)/1000.0); 
    } 
} 

但昨天我的老師告訴我們要使用具有這樣的結構的代碼:

float roundValue(float value, int decimalPlaces) 
{ 
     // Place rounding code here 
     return value; 
} 

我不太清楚怎麼寫這種格式的代碼!我是編碼方面的初學者,所以這可能非常愚蠢。

更新: 所以我只是閱讀下面的所有意見,並試圖編寫代碼,但仍有問題。我的代碼是:

double roundValue(double value, int decimalPlaces) 
{ 
value = roundf(value * pow(10, decimalPlaces))/pow(10, decimalPlaces); 
return value; 
} 
int main(void) 
{ 
int rowIndex = 0; 
int columnIndex = 0; 
double rawData[MAX_ROWS][MAX_COLUMNS]; // 2-dimensional array to store our 
raw data 
double value = rawData[MAX_ROWS][MAX_COLUMNS]; 
int decimalPlaces = 3; 
// Print out the roundup data array 
printf(" --- ROUNDED DATA ---\n"); 
for (rowIndex = 0; rowIndex < MAX_ROWS; rowIndex++) 
{ 
    for (columnIndex = 0; columnIndex < MAX_COLUMNS; columnIndex++) 
    { 
     printf("%.3f ", roundValue(value, 3)); 
    } 
    printf("\n"); 
    } 
    return 0; 
} 

它給我所有的數字只有0。

+0

你需要澄清你的問題,並描述你已經嘗試過的步驟... – PureW

+1

那麼,問你的老師?當你在這個時候,告訴他使用'float'是一個**可怕的**想法,因爲它的精度有限...... –

+0

如果你理解浮點二進制表示,你不會「*認爲*」爲3小數位。如果*真的*需要3位小數,請嘗試使用固定點格式。 –

回答

1

基於this answer,你可以用math.h發現roundf功能:

#include <stdio.h> 
#include <math.h> 

/* function that rounds a float to the specified number of decimals */ 
float roundValue(float value, int decimalPlaces) 
{ 
    value = roundf(value * pow(10, decimalPlaces))/pow(10, decimalPlaces); 
    return value; 
} 


/*to see the results: */ 
int main() 
{ 
    float value = 12.34567; 
    printf("%f", roundValue(value, 3)); 
    return 0; 
} 

編譯/運行:

$ gcc -lm main.c 
$ ./a.out 
12.346000 
+0

這顯然不是由特定的小數位數舍入,而是僅限於由一個線性因素。 – Ext3h

+1

@ Ext3h您能否澄清一下線性因子和小數位之間的區別? – Steephen

+0

@Steephen此答案的原始版本中缺少'pow'。 – Ext3h

1

他只是告訴你寫在你的代碼函數,您可以在main()函數中調用該函數。

因此,不是每次需要循環值時重寫代碼,都可以使用一個函數,給它一個你想計算循環值的數字,它會給你結果,所以你的代碼贏得'不可重複

0

本質上不能這樣做。問題是0.1或0.001不能完全用浮點格式表示。所以你只能四捨五入到最接近的表達式= floor(x * 1000 + 0.5)/1000.0。最好使用雙精度的完整精度,然後在最後一刻舍入,以便顯示。

printf("%.3g", x); 

將爲您達到此目的。與strtod相結合,這也是另一種舍入技術。

+0

使用'sprintf()'是一個合理的選擇,但是使用'%.3g''變量輸出的值很大,因此使用''%.3f''和一個大的'char []'是很有意義的。 – chux

+0

「floor(x * 1000 + 0.5)/ 1000.0」方法給出了許多負面的'x'和各種正面的'x',其中'x + 0.5'不精確。 'round(x * 1000.0)/1000.0;'是一個直接的選擇。 – chux

0

..將任意數字舍入到小數點後3位。
我的老師告訴我們使用的代碼......像float roundValue(float value, int decimalPlaces)

而不去更高的精度,這是很難滿足OP與所有value的最佳答案目標。


舍入浮動指針值)向上或b)至最接近的可表示0.001(或10 -n)通常是在步驟中完成。

1)由10 Ñ
2)回合乘法)向上或b)至最接近
3)除以10 Ñ

float roundValue(float value, int decimalPlaces) { 
    // form the power of 10 
    assert(decimalPlaces >= 0 && decimalPlaces <= 9); 
    int power_of_10 = 1; 
    while (decimalPlaces-- > 0) power_of_10 *= 10; 
    double fpower_of_10 = power_of_10; // or just use `pow(10, decimalPlaces); 

縮放由10的冪引入的不精確。這輕微錯誤在舍入步驟放大。一個簡單的解決方法是使用更高精度的數學。幸運的是,編碼目標始於float值,而double通常具有更高的精度。

縮放由10電源的可引起溢出,但不是很可能valuefloat並且產物是double其具有較寬範圍

double y = value * fpower_of_10; 

    // round 
    double rounded_y = ceil(y); // round up 
    // or 
    double rounded_y = round(y); // round to nearest 

的商很少會提供一個確切數倍的0.001(或任何電力的-10)一個浮點值,該值接近 0.001倍數而是。

y = rounded_y/fpower_of_10; 

    return y; 
} 

用法如下。回想一下,除非你的浮點類型使用FLT_RADIX == 10(現在非常少見,通常爲2),結果只有附近期望的「數字到n小數位」。如果做得好,結果將是最接近的可能的float/double

printf("%f\n", roundValue(123.456789, 3)); 
printf("%.10f\n", roundValue(123.456789, 3)); // to see more 

更多:一個簡單的方法,以避免溢出問題,如果更高的精度不可用或使用是要認識到,了不起C浮動點值沒有小數部分,不需要舍入。

float roundValue(float value, int decimalPlaces) { 
    float int_ptr; 
    float frac_part = modff(value, &int_ptr); 
    if (frac_part == 0) return value; 

    double pow10 = pow(10, decimalPlaces); 
    return round(value * pow10)/pow10; // or ceil() 
} 

還有其他一些細微的問題沒有在這裏提到。 double roundingNaN, rounding mode,round()rint()nearbyint()