Skip to content

Split encoding functions to expose integer encoding for tests #672

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

Closed
drinckes opened this issue Jan 9, 2025 · 8 comments · Fixed by #715 or #721
Closed

Split encoding functions to expose integer encoding for tests #672

drinckes opened this issue Jan 9, 2025 · 8 comments · Fixed by #715 or #721
Assignees
Labels
working Currently being worked on

Comments

@drinckes
Copy link
Contributor

drinckes commented Jan 9, 2025

The encoding function takes two floats (latitude and longitude), converts to integers and then does the encoding. Due to language, platform and/or os implementations, the initial conversion from float to integer can differ slightly.

To enable consistent tests, we want to make the integer encoding a separate function that can be called by the tests.

It should be called something like encodeIntegers, and take as arguments the latitude multiplied by 2.5e7 and longitude multiplied by 8.192e6 (the precision of the longest permissable codes).

This needs to be done for each implementation.

@drinckes
Copy link
Contributor Author

#665 should get merged after any changes to the C implementation to validate against macos (which was our canary that something was up).

@drinckes
Copy link
Contributor Author

drinckes commented Apr 4, 2025

So, in general, here are the changes:

  • The public encode function that receives lat and lng in floats:
    • Multiply each by the precision and truncate to an integer
    • Add latitude max degrees (90) * lat max precision (2.5e7) to the latitude integer and then clip it:
      • If latitude is less than zero, set it to zero
      • If it is greater than or equal to 2 x 90 x 2.5e7, set it to 2 x 90 x 2.5e7 - 1
    • Add longitude max degrees (180) * lng max precision (8.192e6) and then normalise it:
      • If longitude is less than zero, get the modulo remainder of longitude with 2 x 180 x 8.192e6, and then add 2 x 180 x 8.192e6
      • If longitude is greater or equal to 2 x 180 x 8.192e6, then get the modulo remainder of longitude with 2 x 180 x 8.192e6
  • Then the rest of encoding can stay the same.
  • The clipLatitude() and normaliseLongitude() functions, if there were any, might be able to be removed. (They might still be used for a decode nearest, where the precision isn't so important.)

@drinckes
Copy link
Contributor Author

Just VisualBasic to go!

Once that's done, cut a new release (1.0.5) of the project so that the JS CDNs update.

@drinckes
Copy link
Contributor Author

Since the splitting has turned out to not be necessary, and the only implementation I actually split was C, I'm going to merge them back together.

@drinckes
Copy link
Contributor Author

As per the comment in #716 (comment), once I add tests that confirm a code's bounding box contains the original coordinates I get failures. It doesn't matter whether I use Round() or Floor() in the conversion from float to integer, because the issue is with the accuracy of the float representation.

So I thought I wasn't going to have to do all this but it looks as though I will.

@bocops
Copy link
Contributor

bocops commented Apr 15, 2025

Quick reality check - in #716, you state that this mostly happens for 15-digit plus codes. I'm not sure these play a large role in real-world applications, since they have sizes of only some square millimeters, likely smaller than precision/accuracy of the devices they are used on.

Perhaps it would be a sensible alternative to further restrict valid code lengths instead?

@drinckes
Copy link
Contributor Author

Hi @bocops good to hear from you!

I don't think restricing the code length gets us out completely because at least part of the issue is floating point precision. The tests are using "0.1" in the csv file but when it's read in and converted to a float, IEEE-754 means that you actually get 0.1000000000002 (or something) and the difference is sufficient to cause failures.

Also converting the floats to integers using rounding is wrong (issue #717) and I need to address that first.

(I'm on vacation for a week so will think about it and update once I get back.)

@drinckes
Copy link
Contributor Author

drinckes commented May 2, 2025

Due to issue #717 it's apparent that I still need to do this. For example, with a longitude of 129.7:

So since we can't even do simple arithmetic (thanks IEEE 754) I'm going to have to do this split (and add tests for the conversion functions).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
working Currently being worked on
Projects
None yet
2 participants