Understanding double to int64_t conversion

Viewed 9639

So I have two functions, one just casts from double to int64_t, the other calls std::round:

std::int64_t my_cast(double d)
{
  auto t = static_cast<std::int64_t>(d);
  return t;
}

std::int64_t my_round(double d)
{
  auto t = std::round(d);
  return t;
}

They work correctly: cast(3.64) = 3 and round(3.64) = 4. But, when I look at the assembly, they seem to be doing the same thing. So am wondering how they get different results?

$ g++ -std=c++1y -c -O3 ./round.cpp -o ./round.o 
$ objdump -dS ./round.o
./round.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <_Z7my_castd>:
   0:   f2 48 0f 2c c0          cvttsd2si %xmm0,%rax
   5:   c3                      retq
   6:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
   d:   00 00 00

0000000000000010 <_Z8my_roundd>:
  10:   48 83 ec 08             sub    $0x8,%rsp
  14:   e8 00 00 00 00          callq  19 <_Z7my_castd+0x19> <========!!!
  19:   48 83 c4 08             add    $0x8,%rsp
  1d:   f2 48 0f 2c c0          cvttsd2si %xmm0,%rax
  22:   c3                      retq

Disassembly of section .text.startup:

0000000000000030 <_GLOBAL__sub_I__Z7my_castd>:
  30:   48 83 ec 08             sub    $0x8,%rsp
  34:   bf 00 00 00 00          mov    $0x0,%edi
  39:   e8 00 00 00 00          callq  3e <_GLOBAL__sub_I__Z7my_castd+0xe>
  3e:   ba 00 00 00 00          mov    $0x0,%edx
  43:   be 00 00 00 00          mov    $0x0,%esi
  48:   bf 00 00 00 00          mov    $0x0,%edi
  4d:   48 83 c4 08             add    $0x8,%rsp
  51:   e9 00 00 00 00          jmpq   56 <_Z8my_roundd+0x46>

I am not sure what the purpose of that callq on line 14 is for, but, even with that, my_cast and my_round seem to be just doing a cvttsd2si which, I believe is conversion with truncation.

However, the two functions, like I mentioned earlier, produce different (correct) values on the same input (say 3.64)

What is happening?

3 Answers
Related