Hãy xem xét các đoạn mã sau đây:Làm cách nào để printf và scanf xử lý các định dạng độ chính xác của dấu phẩy động?
float val1 = 214.20;
double val2 = 214.20;
printf("float : %f, %4.6f, %4.2f \n", val1, val1, val1);
printf("double: %f, %4.6f, %4.2f \n", val2, val2, val2);
Những kết quả đầu ra:
float : 214.199997, 214.199997, 214.20 | <- the correct value I wanted
double: 214.200000, 214.200000, 214.20 |
Tôi hiểu rằng 214.20
có một đại diện nhị phân vô hạn. Hai yếu tố đầu tiên của dòng đầu tiên có một xấp xỉ của giá trị dự định, nhưng người cuối cùng dường như không có xấp xỉ ở tất cả, và điều này dẫn tôi đến những câu dưới đây:
Làm thế nào để các scanf
, fscanf
, Các hàm printf
, fprintf
(vv) có xử lý các định dạng chính xác không?
Không có độ chính xác được cung cấp, printf
in ra giá trị gần đúng, nhưng với %4.2f
nó đã cho kết quả chính xác. Bạn có thể giải thích cho tôi thuật toán được sử dụng bởi các hàm này để xử lý độ chính xác không?
Cảm ơn bạn đã trả lời, mặc dù câu hỏi của tôi vẫn ở cùng một nơi. Ở vị trí đầu tiên, float không thể chứa giá trị chính xác 214.20, sau đó làm thế nào nó có thể lấy lại nó chỉ với độ chính xác% 4.2f và NOT với% 4.6f. Nó đã làm gì để lấy lại giá trị. Tôi hiểu rằng sự xấp xỉ được thực hiện, nhưng NHỮNG MẪU BIT ĐƯỢC SỬ DỤNG LÀ GÌ ĐƯỢC LƯU TRỮ INTERNIDY 214.199997 ĐỂ TRỞ THÀNH 214,20 VÀ LÀM THẾ NÀO ĐỂ CHÚNG TÔI ĐẾN NHƯ THẾ NÀO? –
Không chắc chắn tôi có được bạn, nhưng đó chỉ là [làm tròn] (http://en.wikipedia.org/wiki/Rounding). Đó là cơ hội thuần túy mà '% 4.2f' cung cấp cho bạn chính xác giá trị mà bạn muốn. Nó vẫn "sai" vì biểu diễn nhị phân là * không * tương đương với 214,20 nhưng đến 214,1999969482421875. Bây giờ, nếu bạn làm tròn "214.1999969482421875" thành 6 chữ số, bạn nhận được "214.199997" bởi vì chữ số thứ 7 là số 9, biến số 6 thành số 7. Nhưng khi bạn chỉ tròn thành 2 chữ số, bạn sẽ nhận được "214,20" vì chữ số thứ 3 là chín, vì vậy bạn cần tăng số 9 trên số thứ hai. Điều đó "tràn" đến 10, chuyển "0,19" thành "0,20". – DarkDust
Oh !! Tôi tin rằng bạn đang cố gắng để nói rằng hoạt động này được thực hiện trong biểu diễn thập phân, và đó là cách 214.199997 được hình thành như là một hiệu ứng tròn của độ chính xác gấp đôi. Bởi vì nó đã được trong đại diện nhị phân, chúng tôi đã xác nhận rằng 214,20 là không thể đại diện trong nhị phân, với tất cả các kỹ năng làm tròn được sử dụng. –