Peter
Peter

Reputation:

C++ difference between 0 and 0.0

Is there a difference between 0 and 0.0 in C++? Which should you use for initializing a double?

Thanks

Upvotes: 21

Views: 45394

Answers (4)

user2356685
user2356685

Reputation:

Here is the Visual-C++ disassembly for:

int main() {
  double x = 0;
  //
  double y = 0.0;
  //
  double z = x * y;
  return 0;
}

Disassembly

int main() {
00007FF758A32230  push        rbp  
00007FF758A32232  push        rdi  
00007FF758A32233  sub         rsp,128h  
00007FF758A3223A  mov         rbp,rsp  
00007FF758A3223D  mov         rdi,rsp  
00007FF758A32240  mov         ecx,4Ah  
00007FF758A32245  mov         eax,0CCCCCCCCh  
00007FF758A3224A  rep stos    dword ptr [rdi]  
  double x = 0;
00007FF758A3224C  xorps       xmm0,xmm0  
00007FF758A3224F  movsd       mmword ptr [x],xmm0  
  //
  double y = 0.0;
00007FF758A32254  xorps       xmm0,xmm0  
00007FF758A32257  movsd       mmword ptr [y],xmm0  
  //
  double z = x * y;
00007FF758A3225C  movsd       xmm0,mmword ptr [x]  
00007FF758A32261  mulsd       xmm0,mmword ptr [y]  
00007FF758A32266  movsd       mmword ptr [z],xmm0  
  return 0;
00007FF758A3226B  xor         eax,eax  
}
00007FF758A3226D  lea         rsp,[rbp+128h]  
00007FF758A32274  pop         rdi  
00007FF758A32275  pop         rbp  
00007FF758A32276  ret

They produced the same assembly. Visual-C++ uses the method of XOR-ing the XMM register with it'self. Had you first loaded the integer 0 then moved it into the XMM register it would have used an extra instruction. Given our hypothesis on how the 0.0 may be loaded as a literal, as well as the extra useless instruction load loading an integer 0 then moving it into a floating-point register, neither is optimal so it seems as though it really doesn't matter because the compiler writer we must assume this optimization has been know for a long time because it is kind of obvious. If 100% portability is required, then it is more portable to write an inline function that manually uses the XOR technique.

Upvotes: 3

Nosredna
Nosredna

Reputation: 86326

I try to keep my constants type-consistent. 0 for ints. 0.0f or 0.f for float, and 0.0 for double.

To me, the most important reason to do this is so the compiler and the programmer see the same thing.

If I do this...

float t=0.5f;
float r;

r= 1 * t;

...should r be assigned 0 or .5? There's no hesitation if I do this instead...

float t=0.5f;
float r;

r= 1.0f * t;

Upvotes: 13

Jim Dennis
Jim Dennis

Reputation: 17520

One appears to be an integer literal, the other a floating point literal. It really doesn't matter to the compiler whether you initialize floats or doubles with integer literals. In any event the literal will be compiled into some internal representation.

I would tend to suggest 0.0 in order to make your intention (to other programmers) explicitly clear.

Upvotes: 6

Rob
Rob

Reputation: 48377

A literal 0 is considered to be an int literal; literal 0.0 is a double literal. When assigning to a double, either will work (since the int can be cast in a widening conversion); however, casting 0.0 to an int is a narrowing conversion, and must be done explicitly; i.e. (int)0.0.

Upvotes: 23

Related Questions