http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48615
--- Comment #1 from Thomas Henlich <thenlich at users dot sourceforge.net> 2011-04-23 07:49:33 UTC --- I think I found the problematic code in write_float: if (f->format == FMT_F || f->format == FMT_EN || f->format == FMT_G || ((f->format == FMT_D || f->format == FMT_E) && dtp->u.p.scale_factor != 0)) { /* Always convert at full precision to avoid double rounding. */ ndigits = MIN_FIELD_WIDTH - 4 - edigits; } else { /* The number of digits is known, so let printf do the rounding. */ if (f->format == FMT_ES) ndigits = f->u.real.d + 1; else ndigits = f->u.real.d; if (ndigits > MIN_FIELD_WIDTH - 4 - edigits) ndigits = MIN_FIELD_WIDTH - 4 - edigits; } "let printf do the rounding" means the result will always be rounded according to the rounding rules of printf, which is for GLIBC: "If the value being printed cannot be expressed accurately in the specified number of digits, the value is rounded to the nearest number that fits."