This repository contains the supplementary material to:
Neri C, Schneider L. "Euclidean affine functions and their application to calendar algorithms". Softw Pract Exper. 2022;1-34. doi: 10.1002/spe.3172.
In particular, it contains instructions on how to build the code and the article's errata.
This work has been presented at C++ Now 2023 and
C++ on Sea 2023.
Executables
Dependencies
Assembly snippets shown in the paper
Other implementations
Errata
A list of CMakePresets is available. For instance, on Linux the preset
gcc.debug.make builds in debug mode using gcc and make. On Windows
msvc.debug.ninja builds in debug mode using msvc and ninja. In general,
preset names have the form compiler.mode.builder where
- compiler is one of
clang(Linux),clang-cl(Windows), gcc (Linux) ormsvc(Windows); - mode is one of
debug,releaseorrelease-symbols; - builder is one of
make(Linux) orninja.
Tip: cmake --list-presets shows the complete list available presets.
To build everything, on the top level directory, run:
$ cmake --preset <preset-name>
$ cmake --build build/<preset-name>
Make sure you have the
cmake
tools installed and, optionally,
clang
tools if you wish to build with clang-cl. Simply open the top level
folder and select one of the available presets.
They are created in the build/<preset-name>/bin directory and the instructions below
assumes this is the current working directory.
| Name | Description |
|---|---|
algorithm_NN_32 |
Paper's algorithm number NN for 32-bits |
algorithm_NN_64 |
Paper's algorithm number NN for 64-bits |
algorithm_tests |
Tests all third party algorithms. |
eaf_tests |
Exhaustive tests for all 32-bits algorithms in the paper |
example_NN |
Paper's example number NN |
fast_eaf |
Calculates fast EAF coefficients |
figure_NN |
Algorithm of figure NN |
info |
Display range limits of all algorithms in the paper |
to_date |
Benchmark of to_date functions |
to_rata_die |
Benchmark of to_rata_date functions |
Algorithms that calculate date from rata die (algorithm_NN_{32|64}
for NN ∈ {01, 03, 05} and figure_12) take rata die at command
line. For instance:
$ ./algorithm_03_32 738734
rata die = 738734
date = 2022 10 1
Algorithms that calculate rata die from date (algorithm_NN_{32|64}
for NN ∈ {02, 04, 06} and figure_13) take year month day at
command line. For instance:
$ ./algorithm_04_32 2022 10 1
rata die = 738734
date = 2022 10 1
Examples, tests, benchmarks and info do not take compulsory arguments at
command line. For instance:
$ ./example_10
Testing:
(5 * N_Y + 461) / 153 == (2141 * N_Y + 197913) /2^16,
for all N_Y in [0, 734[.
Using signed integers...
Pass.
Using unsigned integers...
Pass.
fast_eaf takes rounding a b d k at command line. For instance
(see Example 10):
$ ./fast_eaf down 5 461 153 16
a' = 2141
b' = 197913
d' = 65536
k = 16
upper bound = 734
Tests (algorithm_tests and eaf_tests) uses Google Test and
allows this library's usual options (e.g., --help). The implementations of
our own algorithms are exhaustively tested on their whole range of validity
(spanning millions of years). Implementations of competitor algorithms are
tested on a range spanning 800 years centered at 1 January 1970.
to_date and to_rata_die use
Google Benchmark and allow this
library's usual options (e.g., --help).
The following third part libraries are automatically downloaded at the time of the first build:
Here is a list of Compiler Explorer links for each assembly snippet shown in the paper:
- Figure 5: https://godbolt.org/z/zT4xdzTox
- Figure 6: https://godbolt.org/z/zY87WGz3v
- Figure 7:
- Assembly generation: https://godbolt.org/z/YdfMjGvMd
- Left timeline: https://godbolt.org/z/j9PWvP4qG
- Right timeline: https://godbolt.org/z/3EvPodxo8
- Figure 8:
- Assembly generation: https://godbolt.org/z/KvqqYd71Y
- Left timeline: https://godbolt.org/z/WKEn75qfY
- Right timeline: https://godbolt.org/z/sfMcc6z9j
- Figure 9:
- Assembly generation: https://godbolt.org/z/94TYPd1Tn
- Left timeline: https://godbolt.org/z/WYbz1xY8a
- Right timeline: https://godbolt.org/z/e8Kjbsfd7
- Figure 10: https://godbolt.org/z/coM5esxP4
| System | Language | Author | Link |
|---|---|---|---|
| libstdc++ | C++ | Cassio Neri | 3dfd549 and 97d6161 |
| Linux Kernel | C | Cassio Neri | 2760105 and 1d1bb12 |
| .NET | C# | Sergei Pavlov | PR72712 and PR73277 |
| datealgo-rs | Rust | Nuutti Kotivuori | https://github.com/nakedible/datealgo-rs |
| Firefox | C++ | Cassio Neri | 54ebf8bd2e11 |
| Muen | Ada | Jorge Luis Sacchini | 04e48784 and e24cb651 |
| date-zig | Zig | Travis Staloch | https://github.com/travisstaloch/date-zig |
| Go library | Go | Russ Cox | c5de950 |
| Temporal | Rust | Kevin Ness | PR147 |
Page numbers below refer to the PDF file.
- Page 2, footnote. "2937 and 2821 BC.¹" should read "2937 and 2821 BC. (See Richards.¹)"
- Page 3, line 43. "does not involve strength reduction." should read "since it involves more than strength reduction."
- Page 11, caption of Figure 4. "On the right, the Gregorian calendar" should read "On the right, the proleptic Gregorian calendar".
- Page 14, line 16. "b' = 2928" should read "b' = -2928".
- Page 18, line 5. "x86_64, the mov instruction" should read "the x86_64's mov instruction".
- Page 22, line 29. "n = q∙q + r" should read "n = d∙q + r".
- Page 23, caption of Figure 12. "at least" should read "at least, Nᵤ∈[-12687428, 11248737]. (The range of validity is much larger though.)"
- Page 25, line 15. " f(g(q)) ≥ f(g(q) - 1)" should read " f(g(q) - 1) ≥ f(g(q))".
- Page 26, line 20. "q + 1f(f*(q + 1)) ≤ f(n)" should read "q + 1 = f(f*(q + 1)) ≤ f(n)".
- Page 28, line 23. "sometimes it is Theorem 3" should read "sometimes it is Theorem 2".
- Page 28, line 25. "Q(N)" should read "Q(n)".
- Page 29, line 11. "obtained in in Cavagnino and Werbrouck" should read "obtained in Cavagnino and Werbrouck".
- Page 29, line 20. "2ᵏ - 2ᵏ/%d + d" should read "2ᵏ - 2ᵏ%d + d".