AliceRixte / AliceRixte/convert-units
Improve conversion by factor multiplication
- Ngôn ngữ chính
- Haskell
- Star
- 10
- Fork
- 1
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Mô tả
The conversion `factor` from the `ConversionFactor` class is problematic for several reason.
1. It introduces approximations that could be avoided. For instance when converting Tera to Giga, the factor is `(10^12) / (10^9)` where `10^12` and ` 10^9` are computed first and then the division is done. See #1 .
1. Even with inlining, there is no guarantee that it will be calculated at compile time. With -O2, it does but without, conversion factor will be computed at run time : this is really bad.
Both these problems could be tackled as follow : we introduce a type family that associates units to their factor as a singleton type, something like
``` haskell
class (ConvertibleUnit u a, Fractional a) => ConversionFactor u a where
type FactorOf u a
factor :: forall u a. ConverionFactor u a => a
factor = demote @(FactorOf u) a
```
This way when using the default implementation of factor we always get a statically computed factor, even if -O2 is not on. Also if we use rationals the precision issues are solved.
But $\pi$ is not a rational, and we need it to convert angles. How should we deal with it ? Since `FactorOf` depends on `a`, we can choose different instances depending on which type it will be converted to. So we can adjust the precision of the fraction depending on what we need.
For instance, for `Double`, we have (this is the smallest fraction such that this predicate is true)
``` haskell
> pi == 245850922/78256779
True
```
See [pi approximations as fractions](https://stackoverflow.com/questions/62925107/what-is-the-best-rational-approximation-to-pi-using-a-64-bit-numerator-and-denom)
Hướng dẫn đóng góp
Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này
Đánh giá
Issue này chưa được đánh giá.