Fix overflow with high fixed-point magnitudes

This commit is contained in:
Rangi
2026-09-14 14:27:16 -04:00
parent d082f24a2d
commit ed1ac7309b
4 changed files with 18 additions and 4 deletions
+4 -2
View File
@@ -1010,12 +1010,14 @@ static uint32_t finishReadingFixedPoint(uint32_t integer) {
static_cast<uint32_t>(round(static_cast<double>(dividend) / divisor * (1ULL << precision))); 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 // Carry from `fractional` to `integer` if `round` rounded up to the next integer
assume(fractional <= 1ULL << precision); assume(fractional <= 1ULL << precision);
bool overflowed = false;
if (fractional == 1ULL << precision) { if (fractional == 1ULL << precision) {
++integer; overflowed = integer == UINT32_MAX;
++integer; // This may overflow from UINT32_MAX to 0
fractional = 0; fractional = 0;
} }
if (integer >= 1ULL << (32 - precision)) { if (overflowed || integer >= 1ULL << (32 - precision)) {
warning(WARNING_LARGE_CONSTANT, "Magnitude of fixed-point constant is too large"); warning(WARNING_LARGE_CONSTANT, "Magnitude of fixed-point constant is too large");
return 0; return 0;
} }
+3
View File
@@ -3,15 +3,18 @@ println strfmt("%f", 1.999)
println strfmt("%f", 2.999) println strfmt("%f", 2.999)
println strfmt("%f", 3.999) println strfmt("%f", 3.999)
println strfmt("%f", 16777215.999) println strfmt("%f", 16777215.999)
println strfmt("%f", 4294967295.999)
opt Q16 opt Q16
println strfmt("%f", 1.999999) println strfmt("%f", 1.999999)
println strfmt("%f", 2.999999) println strfmt("%f", 2.999999)
println strfmt("%f", 3.999999) println strfmt("%f", 3.999999)
println strfmt("%f", 65535.999999) println strfmt("%f", 65535.999999)
println strfmt("%f", 4294967295.999999)
opt Q24 opt Q24
println strfmt("%f", 1.999999999) println strfmt("%f", 1.999999999)
println strfmt("%f", 2.999999999) println strfmt("%f", 2.999999999)
println strfmt("%f", 3.999999999) println strfmt("%f", 3.999999999)
println strfmt("%f", 255.999999999) println strfmt("%f", 255.999999999)
println strfmt("%f", 4294967295.999999999)
+8 -2
View File
@@ -1,6 +1,12 @@
warning: Magnitude of fixed-point constant is too large [-Wlarge-constant] warning: Magnitude of fixed-point constant is too large [-Wlarge-constant]
at fixed-point-carry.asm(5) at fixed-point-carry.asm(5)
warning: Magnitude of fixed-point constant is too large [-Wlarge-constant] warning: Magnitude of fixed-point constant is too large [-Wlarge-constant]
at fixed-point-carry.asm(11) at fixed-point-carry.asm(6)
warning: Magnitude of fixed-point constant is too large [-Wlarge-constant] warning: Magnitude of fixed-point constant is too large [-Wlarge-constant]
at fixed-point-carry.asm(17) at fixed-point-carry.asm(12)
warning: Magnitude of fixed-point constant is too large [-Wlarge-constant]
at fixed-point-carry.asm(13)
warning: Magnitude of fixed-point constant is too large [-Wlarge-constant]
at fixed-point-carry.asm(19)
warning: Magnitude of fixed-point constant is too large [-Wlarge-constant]
at fixed-point-carry.asm(20)
+3
View File
@@ -2,11 +2,14 @@
3.00000 3.00000
4.00000 4.00000
0.00000 0.00000
0.00000
2.00000 2.00000
3.00000 3.00000
4.00000 4.00000
0.00000 0.00000
0.00000
2.00000 2.00000
3.00000 3.00000
4.00000 4.00000
0.00000 0.00000
0.00000