Skip to content

Commit 323e6ad

Browse files
jservclaude
andcommitted
Fix precision in fixed-pt conversion to avoid overflow
The previous implementation used ((angle * TWIN_ANGLE_360) >> 15) which caused integer overflow when angle values reached their maximum range of [-9092, 9092]. The multiplication 9092 * 4096 results in 37,240,832, exceeding the 16-bit signed integer limit. This commit simplifies the expression by factoring out the constants: - Original: angle * TWIN_ANGLE_360 / 32768 - Since TWIN_ANGLE_360 = 2^12 and 32768 = 2^15 - Simplified: angle * 2^12 / 2^15 = angle / 8 Use integer division (not right shift) to match original truncate-towards-zero behavior for negative values. Right shift would round towards negative infinity, causing precision errors for ~87.5% of negative angle values (all non-multiples of 8). Benefits: 1. Eliminates integer overflow risk 2. Avoids incorrect double-precision cast 3. Removes floating-point operations 4. Preserves exact precision for all angle values Addresses review comments from @jouae and @weihsinyeh in PR #110. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 2e75289 commit 323e6ad

File tree

1 file changed

+8
-1
lines changed

1 file changed

+8
-1
lines changed

src/trig.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,14 @@ static twin_angle_t twin_atan2_first_quadrant(twin_fixed_t y, twin_fixed_t x)
148148
}
149149
}
150150

151-
return (twin_angle_t) (double) angle / (32768.0) * TWIN_ANGLE_360;
151+
/* Fixed-point conversion: angle / 32768 * TWIN_ANGLE_360
152+
* Simplified: angle * 2^12 / 2^15 = angle / 8
153+
* Use integer division (not right shift) to match original truncate-towards-zero
154+
* behavior for negative values. Right shift would round towards negative infinity,
155+
* causing precision errors for non-multiples of 8.
156+
* Avoids overflow since no intermediate multiplication required.
157+
*/
158+
return (twin_angle_t) (angle / 8);
152159
}
153160

154161
twin_angle_t twin_atan2(twin_fixed_t y, twin_fixed_t x)

0 commit comments

Comments
 (0)