簡體   English   中英

如何在C中四舍五入?

[英]how to do rounding in C?

我有一個代碼示例:

float f = 3.55f;
printf("%.1f\n", f);

結果是3.5,而不是3.6,這是理想的。

float delta = 1e-7;
float f = 3.55f;
printf("%.1f\n", f+delta);

現在的結果是3.6,但是當f為0.0499999f時;

printf("%.1f\n", f+delta);

結果是0.1,而不是0.0。

我需要一個將3.55轉換為3.6、0.0499999轉換為0.0的函數,有人能提供線索嗎?

與許多浮點問題一樣,問題在於您的價值實際上不是3.55

float f = 3.55f;
printf("%.10f\n", f);  // 3.5499999523

另請參見http://floating-point-gui.de/

因此,除非您使用ceil() ,否則永遠不會舍入該值。

通過H2CO3對相關問題的答案進行修改, 可以得到所需的輸出:

float custom_round(float num, int prec)
{
    float trunc = round(num * pow(10, prec+7));
    trunc = round(trunc/pow(10, 7));
    return trunc / pow(10, prec);
}

delta值得出7額外的精度。 我認為這通常不適用,但是對於兩個數字3.55f0.0499999f ,它指向第一個數字將四舍五入而第二個數字將四舍五入的位置。

其他人指出,示例中的十進制值沒有確切的二進制等效項。

然后是增量:

  1. 有一個十進制的增量可能會弄亂您的舍入,因為將一個無法代表的數字加到另一個數字上並不是最佳選擇。
  2. 增量應基於二進制值,其大小為所顯示數字的指數(單精度)的1 /(2 ^ 23)的2 ^或(雙精度)的1 /(2 ^ 52)的數量。

對於范圍在16 <= x <32(指數= 4)中的單個精度數字x,增量應為2 ^(4-23)或2 ^ -19。

問:...將3.55轉換為3.6、0.0499999轉換為0.0的函數...?
答:使用@Kninnug答案,但要保留小數點后1位。

f = round(f * 10) / 10.0;

它會給您3.5因為數字f最初不是 3.55。 是的,您使用文本“ 3.55”初始化了f ,但是C和您的計算機無法精確表示該數字。 您的系統上沒有(浮動)3.55 相反, f的值為大約3.549999952...因為它是最接近的選擇。

如果您仍然想將f舍入為3.6而不是3.5,則需要將f向上微調一點。 當它是3.549999952...時進行取3.549999952...因此它的值> = 3.55,並且當f0.04999990016... (0.0499999也不能精確表示)時,相同的取整使它保持f <0.5。

我們可以增加f最小的值是nextafterf(f, g) g是您希望移動的值。

3.549999952...   --> 3.550000190...
0.04999990016... --> 0.04999990389...

printf("%.1f\n", nextafterf(f, 2*f));
// prints 3.6 when f is 3.549999952...
// prints 0.0 when f is 0.04999990389...

建議您查看@Oli Charlesworth答案中的參考。

此代碼在這里起作用。 我對代碼進行了注釋,以便您理解。

    #include <stdio.h>
    #include <stdlib.h>

int main(int argc, char const *argv[])
{
    float delta = 1e-7;
    float f = 3.55f;

    // Here we minus f (3.55) from the integer of f (3) so 3.55 - 3 = 0.55
    // Then we check whether the value is bigger than 0.5
    if( (f-(int)f) >= 0.5 ) { 
            // If it is, then plus 0.01 to the answer. Thus making it 3.65
        f = f + 0.01;
    } else {
            // If its not, minus 0.01 from the answer.
            // Assuming f is 3.44 this will make f 3.43
        f = f - 0.01;
    }

    // Since you its to the first decimal place, the code above will output 
    // your desired result which is 3.6.
    printf("%.1f\n", f+delta);
    return 0;
}

我希望這能幫到您。 這是一個完整的程序,但您只能使用該函數。

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

//function prototypes
float roundon(float n,int to);

void main(){
    //vars
    float num;
    int roundto;
    puts("Enter the decimal to be rounded");
    scanf("%f",&num);

    puts("Enter the number of decimal places to be rounded");
    scanf("%d",&roundto);

    float rounded= roundon(num,roundto);
    printf("The rounded value is %f\n",rounded);
}

//functions
float roundon(float n, int to){
    //vars
    float rounded;

    int checker=(int) (n*pow(10,(to+1)))%10;
    int dec= (int) (n*pow(10,to));
    if(checker>=5){
        dec++;
    }

    rounded= (float) dec/(pow(10,to));
    return (rounded);
}

暫無
暫無

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

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