【发布时间】:2016-11-12 09:36:02
【问题描述】:
我正在尝试在 Idris 中实现 bigdecimal。到目前为止我有这个:
-- a big decimal has a numerator and a 10^x value
-- it has one type for zero,
--TODO the numerator can't be zero for any other case
--TODO and it can't be divisible by 10
data BigDecimal : (num : Integer) -> (denExp : Integer) -> Type where
Zero : BigDecimal 0 0
BD : (n : Integer) -> (d : Integer) -> BigDecimal n d
我想强制执行上面“TODO”标记的限制。但是,我只是在学习 Idris,所以我什至不确定这种限制是否是个好主意。
一般来说,我正在尝试创建一个能够使用任意精度计算多种(加密)货币的税收计算工具。我希望能够尝试使用证明者来证明程序的一些属性。
所以,我的问题是:
- 尝试强制执行我指定的限制是一个好的设计决策吗?
- 是否可以在 Idris 中进行这种限制?
- 这是 Idris 中 BigDecimal 的良好实现吗?
编辑:我在想类似“BD : (n : Integer) -> ((n = 0)=Void) -> (d : Integer) -> BigDecimal n d”的东西,所以你必须通过证明那 n 不为零。但我真的不知道这是否是个好主意。
编辑 2:针对 Cactus 的评论,这样会更好吗?
data BigDecimal : Type where
Zero : BigDecimal
BD : (n : Integer) -> (s : Integer) -> BigDecimal
【问题讨论】:
-
一般来说,BigDecimals 由一个 BigInteger 表示数字(用于未缩放的值)和一个表示小数点应该在哪里的比例或指数(这也可以是一个负值,所以你可以也代表非常大的值)。不幸的是,我不认识 Idris,所以我无法用那种语言告诉你如何做到这一点。您的分子想法听起来更像是 BigFraction 或 BigRational。 IMO,这会让事情变得有点复杂。
-
实际上我使用的是与您所说的相同的想法。我可能不应该称它为分子,但我在想(分子)/(10 **(分母指数))。
-
那么命名确实很奇怪。您的分子是我的意思的未缩放值,您的分母指数是比例。所以值 1.000 表示为未缩放的值 1000 和比例 3。只需确保在加减时正确放大或缩小,并在乘法或除法时调整比例。此外,如果您除以,请将分子按您想要的精度放大并正确舍入结果。 IE。精度为 10,将分子乘以 10**10 然后除,否则 1 / 10 可能会导致 0 而不是 0.1000000000。
-
您当前的设计意味着每个数字都由一个单独的单例类型表示——我认为这不是您想要的。为什么你有分子和大小作为指标?
-
@"Rudy Velthuis" 重点是让 1000 不是有效的分子。如果我能弄清楚的话,这就是“TODO 并且它不能被 10 整除”应该限制的内容。
标签: decimal bigdecimal idris