Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor times inverse of sqrt 2 calculation #21293

Merged
merged 2 commits into from
Jul 7, 2023
Merged

Conversation

filterpaper
Copy link
Contributor

Description

Diagonal mouse movement is calculated with equal x and y values times 1/sqrt(2). The current function uses bit shifting to divide and then truncates the fractional part to an integer, causing rounding errors.

Example, when x = -7 and y = 7, the current function will return a rounded-down value of 4 instead of 5, when compared to a rounded floating point multiplication with 1/sqrt(2) (0.707106781):

x (x * 181) >> 8 round(x * 0.707106781)
-7 -5 -5
7 4 5

This change uses a simple sign checking ternary operator for the numerator. If negative, subtract half of the denominator before dividing. Otherwise add half of the denominator before dividing. The truncated integer after division will be an accurate rounding that matches floating point operations.

Types of Changes

  • Core
  • Bugfix
  • New feature
  • Enhancement/optimization
  • Keyboard (addition or update)
  • Keymap/layout/userspace (addition or update)
  • Documentation

Checklist

  • My code follows the code style of this project: C, Python
  • I have read the PR Checklist document and have made the appropriate changes.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • I have tested the changes and verified that they work and don't break anything (as well as I can manage).

Diagonal mouse movement is calculated with equal x and y values times 1/sqrt(2).
The current function uses bit shifting to divide and then truncates the fractional part
to an integer, causing rounding errors.

Example, when x = -7 and y = 7, the current function will return a rounded-down value
of `4` instead of `5`, when compared to a rounded floating point multiplication with
1/sqrt(2) (0.707106781):

| x | (x * 181) >> 8 | round(x * 0.707106781) |
|---|----------------|------------------------|
|-7 |     -5         |          -5            |
| 7 |      4         |           5            |

This change uses a simple sign checking ternary operator for the numerator. If negative,
subtract half of the denominator before dividing. Otherwise add half of the denominator
before dividing. The truncated integer after division will be an accurate rounding that
matches floating point operations.
@github-actions github-actions bot added the core label Jun 19, 2023
@drashna drashna requested a review from a team July 3, 2023 19:25
@tzarc tzarc merged commit 9b3ac79 into qmk:develop Jul 7, 2023
@filterpaper filterpaper deleted the sqrt2 branch July 7, 2023 19:57
jesperhellberg pushed a commit to jesperhellberg/qmk_firmware that referenced this pull request Sep 9, 2023
thismarvin pushed a commit to thismarvin/qmk_firmware that referenced this pull request Sep 27, 2023
akeep pushed a commit to akeep/qmk_firmware that referenced this pull request Oct 2, 2023
csolje pushed a commit to csolje/qmk_firmware that referenced this pull request Oct 21, 2023
autoferrit pushed a commit to SpaceRockMedia/bastardkb-qmk that referenced this pull request Dec 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants