Fix more overflows

This commit is contained in:
Erica Fischer
2024-03-18 10:17:18 -07:00
parent 1c97d476c5
commit cc6135dd02
4 changed files with 22 additions and 15 deletions
+12 -7
View File
@@ -307,11 +307,14 @@ double distance_from_line(long long point_x, long long point_y, long long segA_x
// These calculations must be made in integers instead of floating point
// to make them consistent between x86 and arm floating point implementations.
//
// Coordinates may be up to 34 bits, so their product is up to 68 bits,
// In a 32-bit world, coordinates may be up to 34 bits, so their product is up to 68 bits,
// making their sum up to 69 bits. Downshift before multiplying to keep them in range.
double something = ((p2x / 4) * (p2x / 8) + (p2y / 4) * (p2y / 8)) * 32.0;
//
// If the world is bigger than 32 bits, scale down to 32 bits.
long long shift = 1LL << (GLOBAL_DETAIL - 32);
double something = ((p2x / 4 / shift) * (p2x / 8 / shift) + (p2y / 4 / shift) * (p2y / 8 / shift)) * 32.0 * shift * shift;
// likewise
double u = (0 == something) ? 0 : ((point_x - segA_x) / 4 * (p2x / 8) + (point_y - segA_y) / 4 * (p2y / 8)) * 32.0 / (something);
double u = (0 == something) ? 0 : ((point_x - segA_x) / 4 / shift * (p2x / 8 / shift) + (point_y - segA_y) / 4 / shift * (p2y / 8 / shift)) * 32.0 * shift * shift / (something);
if (u >= 1) {
u = 1;
@@ -682,13 +685,15 @@ drawvec fix_polygon(const drawvec &geom) {
xtotal /= count;
ytotal /= count;
long long shift = 1LL << (GLOBAL_DETAIL - 32);
// figure out which point is furthest from the centroid
long long dist2 = 0;
long long furthest = 0;
for (size_t a = 0; a + 1 < ring.size(); a++) {
// division by 16 because these are z0 coordinates and we need to avoid overflow
long long xd = (ring[a].x - xtotal) / 16;
long long yd = (ring[a].y - ytotal) / 16;
long long xd = (ring[a].x - xtotal) / 16 / shift;
long long yd = (ring[a].y - ytotal) / 16 / shift;
long long d2 = xd * xd + yd * yd;
if (d2 > dist2 || (d2 == dist2 && ring[a] < ring[furthest])) {
dist2 = d2;
@@ -703,8 +708,8 @@ drawvec fix_polygon(const drawvec &geom) {
long long furthestb = 0;
for (size_t a = 0; a + 1 < ring.size(); a++) {
// division by 16 because these are z0 coordinates and we need to avoid overflow
long long xd = (ring[a].x - ring[furthest].x) / 16;
long long yd = (ring[a].y - ring[furthest].y) / 16;
long long xd = (ring[a].x - ring[furthest].x) / 16 / shift;
long long yd = (ring[a].y - ring[furthest].y) / 16 / shift;
long long d2 = xd * xd + yd * yd;
if (d2 > dist2b || (d2 == dist2b && ring[a] < ring[furthestb])) {
dist2b = d2;