2

How does C++ round, if signed/unsigned integers are implicitly converted to floats/doubles?

Like:

int myInt = SomeNumberWeCantExpressWithAFloat;
float myFloat = myInt;

My university script says the following: The resulting value is the representable value nearest to the original value, where ties are broken in an implementation-defined fashion.

Please explain how the "nearest representable value" is calculated and what "where ties are broken in an implementation-defined fashion" is supposed to mean.

Edit:
Since I work most of my time with the GCC, please give additional information about what floating point representation the GCC uses by default, if there is one.

Felix Crazzolara
  • 982
  • 9
  • 24
  • I didn't ask how to convert a float/double to int, nor how to round floats. Please reread my question! – Felix Crazzolara Oct 22 '16 at 14:55
  • someNumber shall be a integer, i'll edit this – Felix Crazzolara Oct 22 '16 at 14:56
  • This is not the right duplicate. OP is not asking how to achieve rounding. Instead, he is asking for an explanation of `(int)f` works when `f` is `float`. – Sergey Kalinichenko Oct 22 '16 at 14:58
  • I'm not sure if you understood my question. There are numbers like 4294967294 that you cannot represent with IEEE 754 floating numbers. How does C++ decide to which number such a value is converted to? 4294967294 was just an an example!! Edit: I did not check if this example does work for doubles, but I think you understand what I mean. – Felix Crazzolara Oct 22 '16 at 15:10
  • @Aresloom you didn't mention IEEE 754 in your question. If your question is about that standard, then you should mention it. I have hunch that what you're asking cannot be implemented without knowledge of the representation. – eerorika Oct 22 '16 at 15:21
  • @user2079303 Actually I expected it to be self-evident that we mean IEEE 754 when we talk about floating point numbers. Didn't realise that this isn't the case. – Felix Crazzolara Oct 22 '16 at 17:37

2 Answers2

1

Single-precision floating point numbers have 24-bit mantissa. On systems with 32-bit int representation values above 224 and below -(224) require rounding.

Value 224+1 = 16777217 is the first int that cannot be represented exactly in IEEE binary32 format. Two float representations are available - 16777216, which is below the exact value by 1, and 16777218, which is above the exact value, also by 1. Hence, we have a tie, meaning that C++ is allowed to choose either one of these two representations.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • This is only half true since there are plenty numbers >224 we can represent, perhaps have a look on my answer, Im new on SO but I tried my best. – Felix Crazzolara Oct 22 '16 at 17:33
  • @Aresloom Since your question is about numbers we cannot represent, numbers that we can represent are irrelevant to this discussioy ( standard says that they must be converted exactly). Rounding modes that you describe are all there. The standard says only that if there is ine representation that is closer than the other, then it must win; otherwise, it is up to the implementation which of the many modes to use for conversion i.e. your program must not be dependent on a specific one. – Sergey Kalinichenko Oct 22 '16 at 20:16
1

IEEE 754 specifies 5 different rounding modes about how to round integers:

A very common mode is called: Round to nearest, ties to even.


From GCC Wiki:

Without any explicit options, GCC assumes round to nearest or even and does not care about signalling NaNs. Compare with C99's #pragma STDC FENV ACCESS OFF. Also, see note on x86 and m68080.


Round to nearest, ties to even

From Wikipedia:

Rounding a number y to the nearest integer requires some tie-breaking rule for those cases when y is exactly half-way between two integers — that is, when the fraction part of y is exactly 0.5.

In such a situation the even one would be chosen. This applies for positive as for negative numbers.


Sources:


Feel free to edit. Additional information about conversion rules for rational/irrational numbers is appreciated.

Felix Crazzolara
  • 982
  • 9
  • 24