This lets us remove a ton of special-casing throughout the codebase, and
just generally makes things a lot simpler.
We also remove the ability to take rational powers of `ratio`, including
`sqrt` and `cbrt` helpers, because these are intrinsically ill-defined.
Fixes#369.
The algorithm is exactly the same; we just get our values for
`num_value`, `den_value`, and `exp10` in different ways.
The old printing logic assumed the ratio/Magnitude was an exact rational
number. Formerly, we couldn't even _represent_ anything else, but with
Magnitude, we can. Thus, we guard this assumption with a
`static_assert`. Later on, we can figure out how we want to print
irrational bases and/or rational powers. The point of this change is to
unblock us from moving to the new infrastructure.
For some reason, MSVC seems to want to instantiate these, even though
nobody ever asks for them (as evidenced by the fact that the builds
passed on other architectures).
This commit is huge, but hopefully the cognitive load is not too bad.
The bulk of this commit is just some fairly mechanical updates from
`ratio` to `Magnitude`. Other things to call out:
- `UnitRatio` goes away. We don't need this concept, because Magnitude
can't even _represent_ anything that doesn't satisfy it.
- I commented out some formatting test cases where the precise
expression changes, but the number is completely equivalent. We will
need to decide how we want to handle Magnitude formatting as a
separate, follow-on task. But at least Magnitude gives us all the
tools we'll need to do so!
This resolves a TODO and lets us use arbitrary exponent denominators.
I also attempt to clarify the semantics. This is based on my best
effort of understanding pre-existing concepts in the library, so I hope
I got it right!
This stems from an earlier mistake where I was using primes in the first
wheel, rather than coprimes-to-the-basis. 1 is not prime, so we used to
need to handle it separately (in an implementation which was, to be
clear, wrong). It _is_ coprime, so now we get it for free!
Certain existing units in the library require very large prime
numbers---so large, in fact, that our naive trial division hits the
_iteration limit_ for `constexpr` loops. We don't want to force users
to provide a compiler option override, so we'd better find another way.
The solution is to use the "wheel factorization" algorithm:
https://en.wikipedia.org/wiki/Wheel_factorization
This lets us skip most composite numbers in our trial division. The
implementation presented here is configurable in terms of the size of
the "basis" of primes we use. Bigger bases let us skip more primes, but
at the cost of storing more numbers. Fortunately, it turns out that N=3
was good enough for our purposes.