Hãy xem mã này. 10/3 return 3.333333 604736328125000 và khi tôi nhân với 3 trong calcutor tôi nhận được 9,99, nhưng nếu làm như vậy bằng mã tôi nhận được chính xác 10,00. Làm thế nào nó có thể thực hiện được?Tại sao 10/3 nó chính xác trong C?
#include <stdlib.h>
#include <stdio.h>
int main() {
float v = 10.f/3.f;
float test = v*3.f;
printf("10/3 => %25.25f \n (10/3)*3 => %25.25f\n",v,test);
return 0;
}
Đây là mã lắp ráp mà không printf, biên soạn sử dụng mặc định gcc 7.2.1 thông số:
0000000000400497 <main>:
400497: 55 push rbp
400498: 48 89 e5 mov rbp,rsp
40049b: f3 0f 10 05 b1 00 00 movss xmm0,DWORD PTR [rip+0xb1] # 400554 <_IO_stdin_used+0x4>
4004a2: 00
4004a3: f3 0f 11 45 fc movss DWORD PTR [rbp-0x4],xmm0
4004a8: f3 0f 10 4d fc movss xmm1,DWORD PTR [rbp-0x4]
4004ad: f3 0f 10 05 a3 00 00 movss xmm0,DWORD PTR [rip+0xa3] # 400558 <_IO_stdin_used+0x8>
4004b4: 00
4004b5: f3 0f 59 c1 mulss xmm0,xmm1
4004b9: f3 0f 11 45 f8 movss DWORD PTR [rbp-0x8],xmm0
4004be: b8 00 00 00 00 mov eax,0x0
4004c3: 5d pop rbp
4004c4: c3 ret
4004c5: 66 2e 0f 1f 84 00 00 nop WORD PTR cs:[rax+rax*1+0x0]
4004cc: 00 00 00
4004cf: 90 nop
Tôi nghĩ mulss được làm tròn bởi một tính năng CPU.
Đối với lưu ý, 10/3 trong chương trình GNU BC trả 3,3333333333333333333333 (* 3 => 9,9999) và ở SciLab trả 3,333333333333333 631 (* 3 => 10).
Nhận xét không dành cho thảo luận mở rộng; cuộc hội thoại này đã được [chuyển sang trò chuyện] (http://chat.stackoverflow.com/rooms/160240/discussion-on-question-by-amanda-osvaldo-why-10-3-its-exact-in-c) . – Andy
Kết quả 'mulss' được làm tròn bằng cách sử dụng chế độ làm tròn IEEE754 mặc định, là vòng tròn gần nhất, thậm chí là điểm ngắt. (Chương trình của bạn không sử dụng '#pragma FENV_ACCESS ON' và đặt chế độ làm tròn FP thành một cái gì đó khác, do đó trình biên dịch tạo ra một chương trình sử dụng chế độ làm tròn mặc định.) –