このコードを見てください。 10/3 return 3.333333 604736328125000と私が計算機で3を掛けると、私は9.99になりますが、コードで同じにすると正確に10.00になります。 それはどのように考えられるのですか?なぜ10/3それはCで正確ですか?
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
私はmulssは、CPUの機能により丸みを帯びていると思う:
#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;
}
これはデフォルトのgcc 7.2.1にパラメータを使用してコンパイルのprintfのないアセンブリコードは、あります。メモ、10/3について
GNU BCプログラムは3.3333333333333333333333(* 3 => 9.9999)を返しおよびScilabのに3.333333333333333 631(* 3 => 10)を返します。
コメントは議論の対象外です。この会話は[チャットに移動]されています(http://chat.stackoverflow.com/rooms/160240/discussion-on-question-by-amanda-osvaldo-why-10-3-its-exact-in-c) 。 – Andy
'mulss'の結果は、デフォルトのIEEE754丸めモードを使用して丸められます。丸めモードは、最も近い丸めであり、引き分けとしても機能します。 (あなたのプログラムは '#pragma FENV_ACCESS ON'を使用せず、FP丸めモードを何かに設定するので、コンパイラはデフォルトの丸めモードを使用するプログラムを生成します) –