9

Is there any definition how floating-point values evaluated at compile-time are rounded in C or C++ ? F.e. when I have double d = 1.0 / 3.0; ? I.e. what kind of rounding is done at compile-time.

And is there a definition of what's the default-rounding mode for a thread at runtime (C99's / C++11's fegetround() / fesetround()) ?

And is rounding to integer-values also included in the latter configuration parameters ? Im aware of nearbyint(), but this is specified to bound to the rounding-parameters which can be set by fesetround(). What I'm concerned about is direct casting to an integer.

phuclv
  • 37,963
  • 15
  • 156
  • 475
Bonita Montero
  • 2,817
  • 9
  • 22
  • Do you mean how the calculation you use is mapped to the representable values of a floating point binary mantisse-sign-exponent format? Which is far from "rounding to decimal places"? Maybe this will give you some background: https://stackoverflow.com/questions/588004/is-floating-point-math-broken – Yunnosch Nov 07 '21 at 17:48
  • 2
    I'm pretty sure in all cases the IEEE 754 rules will be followed – Alan Birtles Nov 07 '21 at 17:53
  • 1
    @AlanBirtles: Threre is noe IEEE-754 rule that says what has to be the default-rounding mode at compile time. And there's for sure no rule that says what's the default-rounding mode for a thread and for conversion from floating point values to integers at runtime. That may be all definitions of the language standard and not of IEEE-754. – Bonita Montero Nov 07 '21 at 17:58
  • I think you have answered your own question, @BonitaMontero. If you disagree, then please edit the question to clarify what it is that you are asking. – John Bollinger Nov 07 '21 at 18:04
  • 1
    @AlanBirtles: The C standard does not require C implementations to use IEEE 754. – Eric Postpischil Nov 07 '21 at 18:15
  • @JohnBollinger: No, I didn't answer my question, 1201ProgramAlarm did it. – Bonita Montero Nov 07 '21 at 18:16
  • 2
    @BonitaMontero: IEEE 754-2008 4.3.3 says “The roundTiesToEven rounding-direction attribute shall be the default rounding-direction attribute for results in binary formats” and makes no distinction for compile-time or execution-time calculations. So if a C implementation does adopted IEEE 754 (which the C standard does not require), then it must make round-to-nearest the default. IEEE-754-2019 draft D2.47 says the same thing. – Eric Postpischil Nov 07 '21 at 18:18
  • C 20189 6.3.1.4 1 says “When a finite value of real floating type is converted to an integer type other than`_Bool`, the fractional part is discarded (i.e., the value is truncated toward zero). If the value of the integral part cannot be represented by the integer type, the behavior is undefined.” – Eric Postpischil Nov 07 '21 at 18:20

1 Answers1

6

In both specs (C17 and C++20), the compile time rounding is implementation defined.

In the C++ spec, this is specified in lex.fcon, which says

If the scaled value is not in the range of representable values for its type, the program is ill-formed. Otherwise, the value of a floating-point-literal is the scaled value if representable, else the larger or smaller representable value nearest the scaled value, chosen in an implementation-defined manner.

The C spec has similar language (quote taken from N2176, C17 final draft):

the result is either the nearest representable value, or the larger or smaller representable value immediately adjacent to the nearest representable value, chosen in an implementation-defined manner.

It also recommends that translation time conversion should match execution time conversion by library functions (like strtod) but it is not required. See the description of representable values.

Conversions of floating point values to integers are specified in both to truncate (round towards 0 by discarding the fractional part).

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56