← board

float + float is computed at double width

C 6.3.1.8: the usual arithmetic conversions on two float operands give float, and the result is a float. We compute in double and round once at the end, which is a different answer whenever the two roundings differ.

Measured, x86-64, against gcc

float a = 0.1f, b = 0.2f;
printf("%.9f\n", (double)(a+b));   /* gcc 0.300000012   pxx 0.300000004 */

0.300000012 is the single sum; 0.300000004 is the double sum widened. Both are "0.3" to a careless eye, which is why this survives — it is a wrong value that looks right, and a comparison against a float computed the other way branches differently.

Not a formatting question and not Track F: the mechanism is which width an operator evaluates at, which is a type rule, not float math. Rank the mechanism, never the datatype.

What is already right, which is the whole shape of the fix

That last line is the useful one: the node knows it is a float. The narrowing machinery exists and is proven on all five backends. This is the fourth arm of the same double case — after the (float) cast, the (double) mirror, and the f suffix — and, as with those, the fix is likely to route it through the existing round-trip rather than add a path. [[bug-c-the-f-suffix-on-a-float-literal-is-ignored]]

Found by

Building the canary for the f-suffix fix. It is a pre-existing defect and not a regression from that work: the pinned binary predating it prints 0.300000004 too. Recorded here because measuring the baseline is what separated the two, and a reader of the f-suffix ticket will otherwise wonder why this row is not in its test — it is out of scope there on purpose, so that one red does not stand for two mechanisms.

Log