Why is printf round floating point numbers up?

28,094

Solution 1

C99 §7.19.6.1 The fprintf function

f,F

A double argument representing a floating-point number is converted to decimal notation in the style [−]ddd.ddd, where the number of digits after the decimal-point character is equal to the precision specification. If the precision is missing, it is taken as 6; if the precision is zero and the # flag is not specified, no decimal-point character appears. If a decimal-point character appears, at least one digit appears before it. The value is rounded to the appropriate number of digits.

Solution 2

In addition to existing answers, note that many C compilers try to follow IEEE 754 for floating-point matters. IEEE 754 recommends rounding according to the current rounding mode for conversions from binary floating-point to decimal. The default rounding mode is “round to nearest and ties to even”. Some compilation platforms do not take the rounding mode into account and always round according to the default nearest-even mode in conversions from floating-point to decimal.

Since 76.75 represents the number 7675/100 exactly, it is precisely halfway between 76.7 and 76.8. The latter number is considered the “even” one when applying “round to nearest-even”. This is probably why your compilation platform chose to generate this decimal representation as the conversion to decimal of the floating-point number 76.75.

Solution 3

First of all, why he didn't print 76.7?

Because the language specification says that the low-order digit will be rounded.

how he rounded the number? (some code would help)

This differs implementation-by-implementation. According to the documentation,

The low-order digit shall be rounded in an implementation-defined manner (emphasis added).

Share:
28,094

Related videos on Youtube

Malic Of Sdom
Author by

Malic Of Sdom

Updated on April 23, 2022

Comments

  • Malic Of Sdom
    Malic Of Sdom about 2 years

    I am trying to print some floating point numbers using printf. For example:

    int main()
    {
        printf("%.1f",76.75); 
        return 0;
    }
    

    Output: 76.8

    And I have some questions about the result.

    First of all, why didn't it print 76.7?

    Second, how did it round the number?

    • Jayesh Bhoi
      Jayesh Bhoi almost 10 years
      why it should print 76.7?
    • dan04
      dan04 almost 10 years
      @ecatmur: The answers to that question blame floating-point rounding errors, but this is a different situation because the number 76.75 is represented exactly.
    • Rudy Velthuis
      Rudy Velthuis almost 10 years
      FWIW, your caption is: "Why (does) printf round floating point numbers?". Well, because you tell it to, with the %.1f formatting string.
    • Rudy Velthuis
      Rudy Velthuis almost 10 years
      @dan04: They don't blame rounding errors, they say it is the result of rounding. The answers explain how the value is rounded to one decimal digit, as specified in the format string.
    • Pascal Cuoq
      Pascal Cuoq almost 10 years
      @RudyVelthuis That question is “Why does 37.975 not convert to 37.98?”. This question is “Why does 76.75 convert to 76.8?”. They are symmetrically opposed questions. Besides, the answers there blame rounding in the decimal-to-floating-point conversion that happened during the compilation of 37.975. The correct answer here should explain that this is the normal rounding behavior of floating-point-to-decimal conversion for a value that is exactly midway between two decimal representations.
    • Rudy Velthuis
      Rudy Velthuis almost 10 years
      @Pascal: I don't quite understand. What (other) question is what? It must have been deleted, I guess. The question here is clear, and the answers do not put blame on anything. I don't see any comment by someone called ecatmur either.
    • Rudy Velthuis
      Rudy Velthuis almost 10 years
      @Pascal: I see it now: the close vote. No, it is not a duplicate, IMO.
  • tmyklebu
    tmyklebu almost 10 years
    I've never seen printf round according to the current rounding mode. (I haven't looked in years, though. All I saw was round-to-even and round-to-Java.) Which implementations do that?
  • Pascal Cuoq
    Pascal Cuoq almost 10 years
    @tmyklebu Mac OS X. Linux always rounds to nearest-even, even if the rounding mode was changed. pastebin.com/p3myWBQU (obtained on Mac OS X). Microsoft's compiler has bigger problems than the rounding direction, so I don't think anyone cares about that.
  • Rudy Velthuis
    Rudy Velthuis almost 10 years
    @tmyklebu: always willing to learn something new, so what on earth is round-to-Java? Do you have a link?
  • tmyklebu
    tmyklebu almost 10 years
    @RudyVelthuis: As I recall, it always rounds "1/2" up. Namely, System.out.printf("%.2f", 0.745); outputs 0.75, even though the double 0.745` is strictly less than the rational number 745/1000.
  • Pascal Cuoq
    Pascal Cuoq almost 10 years
    @tmyklebu This is a bad example as 0.745 is not exact. Or perhaps it is a good example of the “Java rounding”, because Java prints it as exact with %.53f. So “Java rounding” would actually appear to be “print as many decimals as required to make the value unambiguous in the origin floating-point type, then apply the rounding rule from primary school”. 0.745 is less than 745/1000 and gets rounded to 0.75. Brilliant! Anyway, if you do not wish to get into the discussion of why Java is <profanity buzzer>, a better example is 0.25.
  • tmyklebu
    tmyklebu almost 10 years
    @PascalCuoq: That's why I picked 0.745, actually. 0.745-the-double is less than 0.745-the-rational, so, printing with "%.2f", it ought to be rounded down under any variation of round-to-nearest. But Java rounds it up with "%.2f".
  • Pascal Cuoq
    Pascal Cuoq almost 10 years
    @tmyklebu yes, the SEP shield is strong with this java rounding thing. Although the details were already in your first comment, I had to rediscover them. It is actually unbelievable enough that my brain edited out the info upon reading your previous comment.
  • tmyklebu
    tmyklebu almost 10 years
    @PascalCuoq: Sorry to put you through that.
  • Ruslan
    Ruslan about 6 years
    Actually, contrary to one of your comments, Linux's glibc rounds according to current rounding mode as of glibs-2.23, although it used to round to nearest unconditionally in 2.14.1 (the two versions I checked). See coliru.stacked-crooked.com/a/690aa6172119e241 for the former.
  • Pascal Cuoq
    Pascal Cuoq about 6 years
    @Ruslan This is good to know, but please note that any comment I wrote, I wrote in 2014. If I had known that the situation was subject to change according to time in addition to changing according to platform, I would probably have described the situation as “a mess”, which was true then and is true now.