1

What is a correct way to convert double to float in c++. Is the conversion implicit?

Question 1: Consider double d = 5.0; and float f;

Which one is correct?

  • f = d;
  • f = (float)d;
  • f = static_cast<float>(d);

Question 2: Now consider we have

char *buffer = readAllBuffer(); 
double *d = (double*)(buffer + offset);
float f;

Which one is now correct?

  • f = d[0];
  • f = (float)d[0];
  • f = static_cast<float>(d[0]);

Thanks in advance!

mohsen_og
  • 774
  • 1
  • 9
  • 31
  • 1
    None of them are really correct considering a `double` can store more than a `float` can so can you loose precision or the value completely – NathanOliver Jun 04 '18 at 13:46
  • 2
    The two questions are really the same. You start with a `double` value in either case and want to convert to a `float` value. In other words, how you obtain the `double` is independent of converting it to `float`. – chris Jun 04 '18 at 13:47
  • @NathanOliver Loosing precision is not problem here. which one gives me the closest number? Since I have to convert double to float? – mohsen_og Jun 04 '18 at 13:48
  • @Mogi - they all will give you the same resulting `f` value. – Sander De Dycker Jun 04 '18 at 13:49
  • @chris I thought the buffer size may have an influence on the value – mohsen_og Jun 04 '18 at 13:49
  • did you perform a google search?! here is the answer http://www.cplusplus.com/forum/general/40303/ and http://www.cplusplus.com/forum/general/64482/ – Saleh Jun 04 '18 at 13:49
  • @MohammadSalehDehghanpour salam, Yep I did. But I could not found what i meant. tnx anyway – mohsen_og Jun 04 '18 at 13:51
  • Your question 2 is illformed as you try to assign a `const double*` to a `double*`. – sebrockm Jun 04 '18 at 13:53
  • 2
    @sebrockm: Not necessarily; only if the original array is read-only and the program attempts to modify data pointed at by `d`. – Bathsheba Jun 04 '18 at 13:54
  • @Bathsheba I meant that it won't compile. He would have to cast away the `const`. Or, of course, directly cast it to non-const `double*`. – sebrockm Jun 04 '18 at 13:58
  • @Aconcagua sry, I think you mixed smth up. You are copying a `const double` to a `double`. But the OP is (was, (s)he corrected it meanwhile) copying a `const double*` to a `double*` which is precisely what `const_cast` is good for. C++ only allows you to do that if you explicitly cast the const away. It does not work implicitly for the reason you stated correctly. Try it out. – sebrockm Jun 04 '18 at 14:13
  • @sebrockm Ah, sorry, my fault. needed to peek back into history - and found exactly my sample for invalid code in slightly different form... Don't even know any more how I came from that to assuming you meant assigning const to non-const by value... Maybe should go to bed - but it's only 1/2 5 pm here???. – Aconcagua Jun 04 '18 at 14:22

2 Answers2

6

They all boil down to the same thing, and the use of arrays is a red herring. You can indeed write

float f = d;

Some folk argue that a static_cast makes code more readable as it sticks out so clearly. It can also defeat warnings that some compilers might issue if a less long-winded form is used.

Naturally of course since a double is a superset of float, you might lose precision. Finally, note that for

float f1 = whatever;
double d1 = f1;
float f2 = d1;

, the C++ standard insists that f1 and f2 must be the same value.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • 1
    static_cast helps to wipe out warning message about truncating from double to float. I belive this is the main reason for using it, not readability – Jeka Jun 04 '18 at 13:57
  • @Jeka: Indeed you're correct. I have all such warnings explicitly suppressed in all my builds. – Bathsheba Jun 04 '18 at 13:58
0

You do have one major issue. This is not allowed:

double *d = (double*)(buffer + offset);

It violates strict aliasing and quite possibly alignment requirements. Instead you need to use memcpy:

double d;
memcpy(&d, buffer + offset, sizeof d);
float f = d;

Either of the cast alternative can be substituted for the last line, the important change is from dereferencing an pointer with incorrect type and alignment to making a bytewise copy.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • It depends of the real type at `buffer + offset` BTW. (can be a `double*` casted to `char*` and restore back to `double*`) (Name of the function suggest it is not the case though). – Jarod42 Jun 04 '18 at 15:34