diff --git a/CHANGELOG b/CHANGELOG index deef8f450dc35f255bfaa7a3ae8e4ce9002ae9e3..9caef53dd7d76eb0f6a4dbb89280cc83789fae96 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ 2020-07-21 David Byers <david.byers@liu.se> + More integer math: + (olc-decode): Converted to use integer math. + Wrote texinfo documentation: * olc.el (olc-parse-length): Removed. Updated documentation comment. diff --git a/olc.el b/olc.el index 64715dca9d12148e4fe9b8af516f1ca09be55165..1b7273bf131167d47e0a4aced735289bd8e1526b 100644 --- a/olc.el +++ b/olc.el @@ -264,10 +264,13 @@ coordinates, an empty code, and so forth). Since this function uses floating point calculations, the results are not identical to e.g. the C++ reference implementation. The differences, however, are extremely small." - (let ((parse (olc-parse-code code)) - (lat -90.0) - (lon -180.0) - (size 20.0)) + (let* ((parse (olc-parse-code code)) + (latscale (* (expt 20 4) (expt 5 5))) + (lonscale (* (expt 20 4) (expt 4 5))) + (lat (* latscale -90)) + (lon (* lonscale -180)) + (latsize (* latscale 20)) + (lonsize (* lonscale 20))) ;; We only deal with long codes (when (olc-parse-short parse) @@ -275,22 +278,28 @@ differences, however, are extremely small." ;; Process the pairs (mapc (lambda (pair) - (setq lat (+ lat (* size (olc-digit-value (car pair)))) - lon (+ lon (* size (olc-digit-value (cdr pair)))) - width size - height size - size (/ size 20.0))) + (setq lat (+ lat (* latsize (olc-digit-value (car pair)))) + lon (+ lon (* lonsize (olc-digit-value (cdr pair)))) + latsize (/ latsize 20) + lonsize (/ lonsize 20))) (olc-parse-pairs parse)) + ;; I'm too tired to figure out why + (setq latsize (* latsize 20) lonsize (* lonsize 20)) + ;; Process the grid (when (olc-parse-grid parse) (mapc (lambda (refine) - (setq width (/ width 4.0) height (/ height 5.0)) + (setq latsize (/ latsize 5) lonsize (/ lonsize 4)) (let ((coord (olc-digit-value refine))) - (setq lat (+ lat (* height (/ coord 4))) - lon (+ lon (* width (% coord 4)))))) + (setq lat (+ lat (* latsize (/ coord 4))) + lon (+ lon (* lonsize (% coord 4)))))) (olc-parse-grid parse))) - (olc-area-create :latlo lat :lonlo lon :lathi (+ lat height) :lonhi (+ lon width)))) + + (olc-area-create :latlo (/ lat (float latscale)) + :lonlo (/ lon (float lonscale)) + :lathi (/ (+ lat latsize) (float latscale)) + :lonhi (/ (+ lon lonsize) (float lonscale))))) (defun olc-encode (lat lon len) diff --git a/test/olctest.el b/test/olctest.el index bf2af42554817625fa02214ec1085f7fc5f1c254..e04234583d5613660745011a5356d7fd324dce9e 100644 --- a/test/olctest.el +++ b/test/olctest.el @@ -18,8 +18,9 @@ (require 'cl-lib) -;; Decode still uses float arithmetic, so results can be slightly off -;; from the test cases. This is deemed acceptable. +;; Due to rounding and floating point representation we can't seem +;; to get closer than 1e-10 to the reference test cases, but sinze +;; it only affects decoding, that is an insignificant error level. (defvar olctest-decode-tolerance 0.0000000001) @@ -196,7 +197,7 @@ (defun olctest-run-all () "Run all tests." - (and (olctest-decode) + (and (olctest-decode)q (olctest-encode) (olctest-shortcodes) (olctest-validity)