Làm cách nào để hạn chế giá trị float chỉ ở hai vị trí sau dấu thập phân trong C?


215

Làm cách nào tôi có thể làm tròn một giá trị float (chẳng hạn như 37.777779) đến hai chữ số thập phân (37,78) trong C?


15
Bạn không thể làm tròn chính xác số đó, bởi vì float(và double) không phải là dấu phẩy động thập phân - chúng là dấu phẩy động nhị phân - vì vậy làm tròn đến vị trí thập phân là vô nghĩa. Bạn có thể làm tròn đầu ra, tuy nhiên.
Pavel Minaev

63
Nó không vô nghĩa; nó không chính xác Có một sự khác biệt.
Brooks Moses

2
Bạn đang mong đợi kiểu làm tròn nào? Half-up hoặc Rounding đến gần nhất chẵn?
Truthseeker Rangwan

Câu trả lời:


407

Nếu bạn chỉ muốn làm tròn số cho mục đích đầu ra, thì "%.2f"chuỗi định dạng thực sự là câu trả lời đúng. Tuy nhiên, nếu bạn thực sự muốn làm tròn giá trị dấu phẩy động để tính toán thêm, một cái gì đó giống như các công việc sau:

#include <math.h>

float val = 37.777779;

float rounded_down = floorf(val * 100) / 100;   /* Result: 37.77 */
float nearest = roundf(val * 100) / 100;  /* Result: 37.78 */
float rounded_up = ceilf(val * 100) / 100;      /* Result: 37.78 */

Lưu ý rằng có ba quy tắc làm tròn khác nhau mà bạn có thể muốn chọn: làm tròn xuống (nghĩa là cắt ngắn sau hai chữ số thập phân), làm tròn đến gần nhất và làm tròn lên. Thông thường, bạn muốn vòng đến gần nhất.

Như một số người khác đã chỉ ra, do sự kỳ quặc của biểu diễn dấu phẩy động, các giá trị tròn này có thể không chính xác là giá trị thập phân "rõ ràng", nhưng chúng sẽ rất gần nhau.

Để biết thêm (nhiều!) Thông tin thêm về làm tròn, và đặc biệt là các quy tắc ngắt kết nối để làm tròn đến gần nhất, hãy xem bài viết Wikipedia về Làm tròn .


4
Nó có thể được sửa đổi để hỗ trợ làm tròn đến độ chính xác tùy ý?

1
@slater Khi bạn nói 'độ chính xác tùy ý', bạn có hỏi về làm tròn đến, ví dụ: ba thay vì hai chữ số thập phân hoặc sử dụng các thư viện triển khai các giá trị thập phân chính xác không giới hạn? Nếu trước đây, làm cho những gì tôi hy vọng là điều chỉnh rõ ràng cho hằng số 100; mặt khác, thực hiện các phép tính chính xác tương tự được hiển thị ở trên, chỉ với bất kỳ thư viện đa độ chính xác nào bạn đang sử dụng.
Dale Hagglund

2
@DaleHagglung Trước đây, cảm ơn bạn. Là điều chỉnh để thay thế 100 bằng pow (10, (int) mong muốnPrecision)?

3
Vâng. Để làm tròn sau k vị trí thập phân, sử dụng hệ số tỷ lệ 10 ^ k. Điều này thực sự dễ dàng để xem nếu bạn viết ra một số giá trị thập phân bằng tay và chơi xung quanh với bội số 10. Giả sử bạn đang làm việc với giá trị 1.23456789 và muốn làm tròn nó đến 3 chữ số thập phân. Các hoạt động có sẵn cho bạn là tròn đến số nguyên . Vậy, làm thế nào để bạn di chuyển ba vị trí thập phân đầu tiên sao cho chúng nằm bên trái dấu thập phân? Tôi hy vọng rõ ràng rằng bạn nhân với 10 ^ 3. Bây giờ bạn có thể làm tròn giá trị đó thành một số nguyên. Tiếp theo, bạn đặt lại ba chữ số thứ tự thấp bằng cách chia cho 10 ^ 3.
Dale Hagglund

1
Tôi có thể làm cho công việc này với doublesquá bằng cách nào đó? Dường như không làm công việc tôi muốn :( (sử dụng floorceil).
Bà Nobody

87

Sử dụng % .2f trong printf. Nó chỉ in 2 điểm thập phân.

Thí dụ:

printf("%.2f", 37.777779);

Đầu ra:

37.77

Cách này tốt hơn vì không mất độ chính xác.
albert

2
@albert Điều này cũng có lợi thế là không mất floatphạm vi như val * 100có thể tràn.
chux - Phục hồi Monica

42

Giả sử bạn đang nói về việc làm tròn giá trị để in, thì câu trả lời của Andrew ColesonAraK là chính xác:

printf("%.2f", 37.777779);

Nhưng lưu ý rằng nếu bạn muốn làm tròn số thành chính xác 37,78 để sử dụng nội bộ (ví dụ: để so sánh với giá trị khác), thì đây không phải là ý tưởng hay, do cách thức hoạt động của các số dấu phẩy động: bạn thường không muốn thực hiện so sánh đẳng thức cho dấu phẩy động, thay vào đó hãy sử dụng giá trị đích +/- giá trị sigma. Hoặc mã hóa số dưới dạng một chuỗi với độ chính xác đã biết và so sánh số đó.

Xem liên kết trong câu trả lời của Greg Hewgill cho một câu hỏi liên quan , cũng bao gồm lý do tại sao bạn không nên sử dụng dấu phẩy động để tính toán tài chính.


1
Được khuyến khích để giải quyết những gì có thể là câu hỏi đằng sau câu hỏi (hoặc câu hỏi nên có đằng sau câu hỏi!). Đó là một điểm khá quan trọng.
Brooks Moses

Trên thực tế 37,78 có thể được trình bày chính xác bằng dấu phẩy động. Float có 11 đến 12 chữ số cho trước. Điều đó là đủ để giải quyết 3778 377.8 hoặc tất cả các loại 4 chữ số thập phân.
Vô danh trắng

@HaryantoCiu yeah đủ công bằng, tôi đã chỉnh sửa câu trả lời của mình một chút.
John Carter

độ chính xác động:printf("%.*f", (int)precision, (double)number);
Minhas Kamal

24

Còn cái này thì sao:

float value = 37.777779;
float rounded = ((int)(value * 100 + .5) / 100.0);

4
-1: a) điều này sẽ không hoạt động đối với các số âm (ok, ví dụ là dương nhưng vẫn). b) bạn không đề cập đến việc không thể lưu trữ giá trị thập phân chính xác trong số float
John Carter

32
@therefromhere: (a) Bạn nói đúng (b) Đây là gì? Một bài kiểm tra trung học?
Daniil

1
tại sao bạn thêm 0,5?
muhammad tayyab

1
Nó là cần thiết để làm theo các quy tắc làm tròn.
Daniil

1
quy tắc làm tròn trong bối cảnh bình luận @Daniil được làm tròn đến gần nhất
Shmil The Cat

20
printf("%.2f", 37.777779);

Nếu bạn muốn ghi vào chuỗi C:

char number[24]; // dummy size, you should take care of the size!
sprintf(number, "%.2f", 37.777779);

@Sinan: Tại sao phải chỉnh sửa? @AraK: Không, bạn nên chăm sóc kích thước :). Sử dụng snprintf ().
aib

1
@aib: Tôi đoán vì / ** / là những bình luận kiểu C và câu hỏi được gắn thẻ cho C
Michael Haren

5
C89 chỉ cho phép / ** / - style, C99 giới thiệu hỗ trợ cho // - style. Sử dụng trình biên dịch khập khiễng / cũ (hoặc chế độ C89) và bạn sẽ không thể sử dụng // - style. Phải nói rằng, đó là năm 2009, hãy xem xét cả hai phong cách C và C ++.
Andrew Coleson

11

Không có cách nào để làm tròn số này floatđến số khác floatvì số được làm tròn floatcó thể không thể biểu thị được (giới hạn số dấu phẩy động). Chẳng hạn, giả sử bạn làm tròn 37.777779 đến 37,78, nhưng số đại diện gần nhất là 37,781.

Tuy nhiên, bạn có thể "làm tròn" a floatbằng cách sử dụng hàm chuỗi định dạng.


3
Điều này không khác gì khi nói "không có cách nào để chia hai phao và nổi, bởi vì kết quả được chia có thể không thể biểu thị được", điều này có thể đúng nhưng không liên quan. Phao luôn không chính xác, ngay cả đối với một cái gì đó cơ bản như bổ sung; giả định luôn luôn là những gì bạn thực sự nhận được là "số float gần đúng nhất với câu trả lời được làm tròn chính xác".
Brooks Moses

Ý tôi là bạn không thể làm tròn số a floatđến n vị trí thập phân và sau đó mong đợi kết quả luôn có n vị trí thập phân. Bạn vẫn sẽ nhận được một float, chỉ không phải là người bạn mong đợi.
Andrew Keeton

9

Ngoài ra, nếu bạn đang sử dụng C ++, bạn có thể tạo một hàm như thế này:

string prd(const double x, const int decDigits) {
    stringstream ss;
    ss << fixed;
    ss.precision(decDigits); // set # places after decimal
    ss << x;
    return ss.str();
}

Sau đó, bạn có thể xuất bất kỳ gấp đôi nào myDoublevới các nvị trí sau dấu thập phân với mã như sau:

std::cout << prd(myDouble,n);

7

Bạn vẫn có thể sử dụng:

float ceilf(float x); // don't forget #include <math.h> and link with -lm.

thí dụ:

float valueToRound = 37.777779;
float roundedValue = ceilf(valueToRound * 100) / 100;

Điều này cắt ngắn ở điểm thập phân (nghĩa là sẽ tạo ra 37) và anh ta cần làm tròn đến hai vị trí sau dấu thập phân.
Pavel Minaev

Làm tròn đến hai vị trí sau dấu thập phân là một biến thể tầm thường, tuy nhiên (nhưng vẫn nên được đề cập trong câu trả lời; ZeroCool, muốn thêm một chỉnh sửa?): Float roundValue = ceilf (valueToRound * 100.0) / 100.0;
Brooks Moses

Đang trong trạng thái ngủ :)
ZeroCool

Tại sao giải pháp này không phổ biến hơn? Điều này hoạt động chính xác như thế nào với mã tối thiểu. Có một số cảnh báo với nó?
Andy

7

Trong C ++ (hoặc trong C với phôi kiểu C), bạn có thể tạo hàm:

/* Function to control # of decimal places to be output for x */
double showDecimals(const double& x, const int& numDecimals) {
    int y=x;
    double z=x-y;
    double m=pow(10,numDecimals);
    double q=z*m;
    double r=round(q);

    return static_cast<double>(y)+(1.0/m)*r;
}

Sau đó std::cout << showDecimals(37.777779,2);sẽ sản xuất: 37,78.

Rõ ràng là bạn không thực sự cần phải tạo cả 5 biến trong hàm đó, nhưng tôi để chúng ở đó để bạn có thể thấy logic. Có thể có các giải pháp đơn giản hơn, nhưng điều này hiệu quả với tôi - đặc biệt là vì nó cho phép tôi điều chỉnh số chữ số sau chữ số thập phân khi tôi cần.


5

Luôn luôn sử dụng printfhọ các chức năng cho việc này. Ngay cả khi bạn muốn nhận giá trị dưới dạng float, tốt nhất bạn nên sử dụng snprintfđể lấy giá trị làm tròn dưới dạng chuỗi và sau đó phân tích lại bằng atof:

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

double dround(double val, int dp) {
    int charsNeeded = 1 + snprintf(NULL, 0, "%.*f", dp, val);
    char *buffer = malloc(charsNeeded);
    snprintf(buffer, charsNeeded, "%.*f", dp, val);
    double result = atof(buffer);
    free(buffer);
    return result;
}

Tôi nói điều này bởi vì cách tiếp cận được hiển thị bởi câu trả lời được bình chọn hàng đầu hiện tại và một số cách khác ở đây - nhân với 100, làm tròn đến số nguyên gần nhất, sau đó chia cho 100 lần nữa - bị sai theo hai cách:

  • Đối với một số giá trị, nó sẽ làm tròn sai hướng vì phép nhân với 100 thay đổi chữ số thập phân xác định hướng làm tròn từ 4 sang 5 hoặc ngược lại, do sự thiếu chính xác của các số dấu phẩy động
  • Đối với một số giá trị, nhân và sau đó chia cho 100 không đi khứ hồi, có nghĩa là ngay cả khi không làm tròn số thì kết quả cuối cùng sẽ sai

Để minh họa loại lỗi đầu tiên - hướng làm tròn đôi khi bị sai - hãy thử chạy chương trình này:

int main(void) {
    // This number is EXACTLY representable as a double
    double x = 0.01499999999999999944488848768742172978818416595458984375;

    printf("x: %.50f\n", x);

    double res1 = dround(x, 2);
    double res2 = round(100 * x) / 100;

    printf("Rounded with snprintf: %.50f\n", res1);
    printf("Rounded with round, then divided: %.50f\n", res2);
}

Bạn sẽ thấy đầu ra này:

x: 0.01499999999999999944488848768742172978818416595459
Rounded with snprintf: 0.01000000000000000020816681711721685132943093776703
Rounded with round, then divided: 0.02000000000000000041633363423443370265886187553406

Lưu ý rằng giá trị chúng tôi bắt đầu bằng nhỏ hơn 0,015 và vì vậy câu trả lời đúng về mặt toán học khi làm tròn nó đến 2 chữ số thập phân là 0,01. Tất nhiên, 0,01 không thể biểu diễn chính xác như một đôi, nhưng chúng tôi hy vọng kết quả của chúng tôi sẽ là gấp đôi gần nhất với 0,01. Sử dụng snprintfcho chúng ta kết quả đó, nhưng sử dụng round(100 * x) / 100cho chúng ta 0,02, đó là sai. Tại sao? Bởi vì 100 * xcho chúng tôi chính xác 1,5 như kết quả. Nhân với 100 do đó thay đổi hướng chính xác để làm tròn.

Để minh họa loại lỗi thứ hai - kết quả đôi khi bị sai do * 100/ 100không thực sự là nghịch đảo của nhau - chúng ta có thể thực hiện một bài tập tương tự với một số rất lớn:

int main(void) {
    double x = 8631192423766613.0;

    printf("x: %.1f\n", x);

    double res1 = dround(x, 2);
    double res2 = round(100 * x) / 100;

    printf("Rounded with snprintf: %.1f\n", res1);
    printf("Rounded with round, then divided: %.1f\n", res2);
}

Số của chúng tôi bây giờ thậm chí không có một phần nhỏ; nó là một giá trị nguyên, chỉ được lưu trữ với loại double. Vì vậy, kết quả sau khi làm tròn nó sẽ là cùng một số chúng ta bắt đầu, phải không?

Nếu bạn chạy chương trình trên, bạn sẽ thấy:

x: 8631192423766613.0
Rounded with snprintf: 8631192423766613.0
Rounded with round, then divided: 8631192423766612.0

Giáo sư. snprintfPhương pháp của chúng tôi trả về kết quả đúng một lần nữa, nhưng cách tiếp cận nhân-sau-vòng-sau-sau-chia-thất bại. Đó là bởi vì giá trị chính xác về mặt toán học của 8631192423766613.0 * 100,, 863119242376661300.0không thể biểu diễn chính xác như một đôi; giá trị gần nhất là 863119242376661248.0. Khi bạn chia lại cho 100, bạn nhận được8631192423766612.0 - một số khác với số bạn đã bắt đầu.

Hy vọng rằng đó là một minh chứng đầy đủ rằng việc sử dụng roundfđể làm tròn đến một số vị trí thập phân bị hỏng và snprintfthay vào đó bạn nên sử dụng . Nếu điều đó cảm thấy như một vụ hack khủng khiếp đối với bạn, có lẽ bạn sẽ yên tâm bởi kiến ​​thức rằng về cơ bản đó là những gì CPython làm .


+1 cho một ví dụ cụ thể về những gì sai với câu trả lời của tôi và những câu hỏi tương tự, nhờ vào sự kỳ lạ của điểm nổi IEEE và cung cấp một giải pháp thay thế đơn giản. Tôi đã nhận thức được ngoại vi, một thời gian dài trở lại đây, rất nhiều nỗ lực được đưa vào in ấn và bạn bè với tôi họ an toàn cho các giá trị dấu phẩy tròn. Tôi đoán rằng công việc được thực hiện sau đó có thể được hiển thị ở đây.
Dale Hagglund

Ahem ... Xin lỗi vì món salad từ gần cuối, mà bây giờ đã quá muộn để chỉnh sửa. Điều tôi muốn nói là "... rất nhiều nỗ lực dành cho printf và bạn bè để làm cho họ an toàn ..."
Dale Hagglund

4

Sử dụng float roundf(float x) .

"Các hàm làm tròn làm tròn đối số của chúng thành giá trị nguyên gần nhất ở định dạng dấu phẩy động, làm tròn các trường hợp nửa chừng từ 0, bất kể hướng làm tròn hiện tại." C11dr7.12.9.5

#include <math.h>
float y = roundf(x * 100.0f) / 100.0f; 

Tùy thuộc vào floatviệc triển khai của bạn , những con số có vẻ như là một nửa. như dấu phẩy động thường là định hướng cơ sở 2. Hơn nữa, làm tròn chính xác đến gần nhất 0.01trong tất cả các trường hợp "nửa đường" là thách thức nhất.

void r100(const char *s) {
  float x, y;
  sscanf(s, "%f", &x);
  y = round(x*100.0)/100.0;
  printf("%6s %.12e %.12e\n", s, x, y);
}

int main(void) {
  r100("1.115");
  r100("1.125");
  r100("1.135");
  return 0;
}

 1.115 1.115000009537e+00 1.120000004768e+00  
 1.125 1.125000000000e+00 1.129999995232e+00
 1.135 1.134999990463e+00 1.139999985695e+00

Mặc dù "1.115" là "nửa đường" giữa 1.11 và 1.12, khi được chuyển đổi thành float, giá trị 1.115000009537...này không còn là "nửa đường", mà gần hơn với 1.12 và làm tròn đến gần nhất floatcủa1.120000004768...

"1.125" là "nửa đường" trong khoảng từ 1.12 đến 1.13, khi được chuyển đổi thành float, giá trị chính xác 1.125và là "nửa đường". Nó làm tròn tới 1,13 do liên kết với quy tắc chẵn và làm tròn đến gần nhất floatcủa1.129999995232...

Mặc dù "1.135" là "nửa đường" trong khoảng từ 1.13 đến 1.14, khi được chuyển đổi thành float, giá trị 1.134999990463...này không còn là "nửa đường", mà gần hơn với 1.13 và làm tròn đến gần nhất floatcủa1.129999995232...

Nếu mã được sử dụng

y = roundf(x*100.0f)/100.0f;

Mặc dù "1,135" là "một nửa chiều" giữa 1,13 và 1,14, khi chuyển đổi sang float, giá trị là 1.134999990463...và không còn là "một nửa chiều", nhưng gần gũi hơn với 1,13 nhưng không đúng vòng tới floatcủa 1.139999985695...do độ chính xác hạn chế hơn floatso với double. Giá trị không chính xác này có thể được xem là chính xác, tùy thuộc vào mục tiêu mã hóa.


4

Tôi đã tạo macro này để làm tròn số float. Thêm nó trong tiêu đề / là tập tin của bạn

#define ROUNDF(f, c) (((float)((int)((f) * (c))) / (c)))

Đây là một ví dụ:

float x = ROUNDF(3.141592, 100)

x bằng 3,14 :)


Điều này cắt ngắn, nhưng câu hỏi yêu cầu làm tròn. Ngoài ra, nó có thể bị lỗi làm tròn trong các phép toán dấu phẩy động.
Eric Postpischil

3
double f_round(double dval, int n)
{
    char l_fmtp[32], l_buf[64];
    char *p_str;
    sprintf (l_fmtp, "%%.%df", n);
    if (dval>=0)
            sprintf (l_buf, l_fmtp, dval);
    else
            sprintf (l_buf, l_fmtp, dval);
    return ((double)strtod(l_buf, &p_str));

}

Đây nlà số thập phân

thí dụ:

double d = 100.23456;

printf("%f", f_round(d, 4));// result: 100.2346

printf("%f", f_round(d, 2));// result: 100.23

-1 vì bốn lý do: 1) thiếu giải thích, 2) lỗ hổng để tràn bộ đệm - điều này sẽ tràn, và do đó hoàn toàn có thể bị sập, nếu dvallà 3 lớn) khối lạ if/ elsekhối nơi bạn thực hiện chính xác điều tương tự trong mỗi nhánh và 4) việc sử dụng quá mức sprintfđể xây dựng trình xác định định dạng cho sprintfcuộc gọi thứ hai ; đơn giản hơn là chỉ sử dụng .*và chuyển giá trị kép và số vị trí thập phân làm đối số cho cùng một sprintfcuộc gọi.
Đánh dấu Amery

3

Định nghĩa mã:

#define roundz(x,d) ((floor(((x)*pow(10,d))+.5))/pow(10,d))

Các kết quả :

a = 8.000000
sqrt(a) = r = 2.828427
roundz(r,2) = 2.830000
roundz(r,3) = 2.828000
roundz(r,5) = 2.828430

0

Trước tiên hãy để tôi biện minh cho lý do của mình để thêm một câu trả lời khác cho câu hỏi này. Trong một thế giới lý tưởng, làm tròn không thực sự là một vấn đề lớn. Tuy nhiên, trong các hệ thống thực, bạn có thể cần phải giải quyết một số vấn đề có thể dẫn đến làm tròn có thể không như bạn mong đợi. Ví dụ: bạn có thể thực hiện các tính toán tài chính trong đó kết quả cuối cùng được làm tròn và hiển thị cho người dùng dưới dạng 2 chữ số thập phân; các giá trị tương tự này được lưu trữ với độ chính xác cố định trong cơ sở dữ liệu có thể bao gồm hơn 2 vị trí thập phân (vì nhiều lý do; không có số vị trí tối ưu để giữ ... phụ thuộc vào các tình huống cụ thể mà mỗi hệ thống phải hỗ trợ, ví dụ: các mặt hàng nhỏ có giá là các phân số của một xu trên mỗi đơn vị); và, tính toán dấu phẩy động được thực hiện trên các giá trị trong đó kết quả là cộng / trừ epsilon. Tôi đã phải đối mặt với những vấn đề này và phát triển chiến lược của riêng tôi trong những năm qua. Tôi sẽ không tuyên bố rằng tôi đã đối mặt với mọi kịch bản hoặc có câu trả lời tốt nhất, nhưng dưới đây là một ví dụ về cách tiếp cận của tôi cho đến nay khắc phục những vấn đề này:

Giả sử 6 vị trí thập phân được coi là đủ chính xác để tính toán trên phao / đôi (một quyết định tùy ý cho ứng dụng cụ thể), sử dụng hàm / phương pháp làm tròn sau:

double Round(double x, int p)
{
    if (x != 0.0) {
        return ((floor((fabs(x)*pow(double(10.0),p))+0.5))/pow(double(10.0),p))*(x/fabs(x));
    } else {
        return 0.0;
    }
}

Làm tròn đến 2 vị trí thập phân để trình bày kết quả có thể được thực hiện như sau:

double val;
// ...perform calculations on val
String(Round(Round(Round(val,8),6),2));

Cho val = 6.825, kết quả là6.83 như mong đợi.

Đối với val = 6.824999, kết quả là 6.82. Ở đây giả định là việc tính toán dẫn đến kết quả chính xác6.824999 và vị trí thập phân thứ 7 bằng không.

Đối với val = 6.8249999, kết quả là 6.83. Vị trí thập phân thứ 7 9trong trường hợp này làm cho Round(val,6)hàm đưa ra kết quả mong đợi. Trong trường hợp này, có thể có bất kỳ số lượng dấu9 .

Đối với val = 6.824999499999, kết quả là 6.83. Làm tròn đến vị trí thập phân thứ 8 là bước đầu tiên, nghĩa là Round(val,8)xử lý một trường hợp khó chịu, theo đó kết quả điểm nổi được tính toán sẽ được tính 6.8249995, nhưng được biểu thị bên trong như6.824999499999... .

Cuối cùng, ví dụ từ câu hỏi ... val = 37.777779kết quả là37.78 .

Cách tiếp cận này có thể được khái quát hơn như:

double val;
// ...perform calculations on val
String(Round(Round(Round(val,N+2),N),2));

Trong đó N là độ chính xác được duy trì cho tất cả các tính toán trung gian trên phao / đôi. Điều này hoạt động trên các giá trị tiêu cực là tốt. Tôi không biết cách tiếp cận này có đúng về mặt toán học cho tất cả các khả năng hay không.


0

Mã C đơn giản để làm tròn số:

float n = 3.56;
printf("%.f", n);

Điều này sẽ xuất ra:

4

-1

... Hoặc bạn có thể làm theo cách cũ mà không cần bất kỳ thư viện nào:

float a = 37.777779;

int b = a; // b = 37    
float c = a - b; // c = 0.777779   
c *= 100; // c = 77.777863   
int d = c; // d = 77;    
a = b + d / (float)100; // a = 37.770000;

Điều đó tất nhiên nếu bạn muốn loại bỏ thông tin bổ sung từ số.


-2

hàm này lấy số và độ chính xác và trả về số làm tròn

float roundoff(float num,int precision)
{
      int temp=(int )(num*pow(10,precision));
      int num1=num*pow(10,precision+1);
      temp*=10;
      temp+=5;
      if(num1>=temp)
              num1+=10;
      num1/=10;
      num1*=10;
      num=num1/pow(10,precision+1);
      return num;
}

nó chuyển đổi số dấu phẩy động thành int bằng cách dịch chuyển trái điểm và kiểm tra điều kiện lớn hơn năm.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.