@
wisej c++里并不是 12.3 仍然是 12.299999,只是在输出的时候有些额外的 workaround
------------------------------------源码----------------------------------------
#include <stdio.h>
int flg = 0;
int main()
{
double v1 = 4.1;
double v2 = 3;
printf("%lf",v1*v2);
}
---------------------------------------------------------------------------------
----------------------------------编译结果------------------------------------
flg:
.zero 4
.LC2:
.string "%lf"
main:
push rbp
mov rbp, rsp
sub rsp, 16
movsd xmm0, QWORD PTR .LC0[rip]
movsd QWORD PTR [rbp-8], xmm0
movsd xmm0, QWORD PTR .LC1[rip]
movsd QWORD PTR [rbp-16], xmm0
movsd xmm0, QWORD PTR [rbp-8]
mulsd xmm0, QWORD PTR [rbp-16]
mov edi, OFFSET FLAT:.LC2
mov eax, 1
call printf
mov eax, 0
leave
ret
.LC0:
.long 1717986918
.long 1074816614
.LC1:
.long 0
.long 1074266112
(可以直接在
https://gcc.godbolt.org/实时查看代码段在不同编译器下的结果)---------------------------------------GDB-----------------------------------------
[----------------------------------registers-----------------------------------]
RAX: 0x400526 (<main>: push rbp)
RBX: 0x0
RCX: 0x0
RDX: 0x7fffffffddc8 --> 0x7fffffffe1b6 ("XDG_SEAT=seat0")
RSI: 0x7fffffffddb8 --> 0x7fffffffe1ab ("/tmp/a.out")
RDI: 0x1
RBP: 0x7fffffffdcd0 --> 0x400570 (<__libc_csu_init>: push r15)
RSP: 0x7fffffffdcc0 --> 0x4008000000000000
RIP: 0x400552 (<main+44>: mov edi,0x4005f8)
R8 : 0x4005e0 (<__libc_csu_fini>: repz ret)
R9 : 0x7ffff7de7ab0 (<_dl_fini>: push rbp)
R10: 0x846
R11: 0x7ffff7a2d740 (<__libc_start_main>: push r14)
R12: 0x400430 (<_start>: xor ebp,ebp)
R13: 0x7fffffffddb0 --> 0x1
R14: 0x0
R15: 0x0
EFLAGS: 0x206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x400543 <main+29>: movsd QWORD PTR [rbp-0x8],xmm0
0x400548 <main+34>: movsd xmm0,QWORD PTR [rbp-0x10]
0x40054d <main+39>: mulsd xmm0,QWORD PTR [rbp-0x8]
=> 0x400552 <main+44>: mov edi,0x4005f8
0x400557 <main+49>: mov eax,0x1
0x40055c <main+54>: call 0x400400 <printf@plt>
0x400561 <main+59>: mov eax,0x0
0x400566 <main+64>: leave
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffdcc0 --> 0x4008000000000000
0008| 0x7fffffffdcc8 --> 0x4010666666666666
0016| 0x7fffffffdcd0 --> 0x400570 (<__libc_csu_init>: push r15)
0024| 0x7fffffffdcd8 --> 0x7ffff7a2d830 (<__libc_start_main+240>: mov edi,eax)
0032| 0x7fffffffdce0 --> 0x0
0040| 0x7fffffffdce8 --> 0x7fffffffddb8 --> 0x7fffffffe1ab ("/tmp/a.out")
0048| 0x7fffffffdcf0 --> 0x100000000
0056| 0x7fffffffdcf8 --> 0x400526 (<main>: push rbp)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
0x0000000000400552 in main ()
gdb-peda$ p $xmm0
$1 = {
v4_float = {-1.58818668e-23, 2.63437486, 0, 0},
v2_double = {12.299999999999999, 0},
v16_int8 = {0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x28, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
v8_int16 = {0x9999, 0x9999, 0x9999, 0x4028, 0x0, 0x0, 0x0, 0x0},
v4_int32 = {0x99999999, 0x40289999, 0x0, 0x0},
v2_int64 = {0x4028999999999999, 0x0},
uint128 = 0x00000000000000004028999999999999
}
gdb-peda$
可以很清楚地看到算出来就是 12.29999999999999,这是机器码已经决定了的。只是在 printf 后被%lf 重新格式化成了 12.300000