Fix rounding of fixed-point constants where fractional digits should carry into integer part (#2088)

This commit is contained in:
Rangi
2026-09-14 13:52:39 -04:00
committed by GitHub
parent 7746ddbf2b
commit d082f24a2d
5 changed files with 48 additions and 7 deletions
+11 -5
View File
@@ -1005,14 +1005,20 @@ static uint32_t finishReadingFixedPoint(uint32_t integer) {
precision = options.fixPrecision;
}
if (integer >= (1ULL << (32 - precision))) {
warning(WARNING_LARGE_CONSTANT, "Magnitude of fixed-point constant is too large");
return 0;
}
// Cast to unsigned avoids undefined overflow behavior
uint32_t fractional =
static_cast<uint32_t>(round(static_cast<double>(dividend) / divisor * (1ULL << precision)));
// Carry from `fractional` to `integer` if `round` rounded up to the next integer
assume(fractional <= 1ULL << precision);
if (fractional == 1ULL << precision) {
++integer;
fractional = 0;
}
if (integer >= 1ULL << (32 - precision)) {
warning(WARNING_LARGE_CONSTANT, "Magnitude of fixed-point constant is too large");
return 0;
}
return (integer << precision) | fractional;
}
+17
View File
@@ -0,0 +1,17 @@
opt Q8
println strfmt("%f", 1.999)
println strfmt("%f", 2.999)
println strfmt("%f", 3.999)
println strfmt("%f", 16777215.999)
opt Q16
println strfmt("%f", 1.999999)
println strfmt("%f", 2.999999)
println strfmt("%f", 3.999999)
println strfmt("%f", 65535.999999)
opt Q24
println strfmt("%f", 1.999999999)
println strfmt("%f", 2.999999999)
println strfmt("%f", 3.999999999)
println strfmt("%f", 255.999999999)
+6
View File
@@ -0,0 +1,6 @@
warning: Magnitude of fixed-point constant is too large [-Wlarge-constant]
at fixed-point-carry.asm(5)
warning: Magnitude of fixed-point constant is too large [-Wlarge-constant]
at fixed-point-carry.asm(11)
warning: Magnitude of fixed-point constant is too large [-Wlarge-constant]
at fixed-point-carry.asm(17)
+12
View File
@@ -0,0 +1,12 @@
2.00000
3.00000
4.00000
0.00000
2.00000
3.00000
4.00000
0.00000
2.00000
3.00000
4.00000
0.00000
+2 -2
View File
@@ -5,9 +5,9 @@ $18B
$62B85
$4
$10000
$20000
$10000
$10000
$10000
$20000
$C570A
$13333
$13333