3个不稳定版本
0.2.0 | 2024年5月20日 |
---|---|
0.1.1 | 2021年10月13日 |
0.1.0 | 2021年10月13日 |
#162 in 游戏开发
21 每月下载量
82KB
2K SLoC
break-eternity
Patashu的break_eternity.js的移植。
一个数值库,可以表示从10^^1e308这样大的数到10^-(10^^1e308)这样小的数。
这个库更注重速度而不是精度,旨在供游戏使用。
额外功能
此crate有2个额外功能可供使用
serde
,增加了对serde的支持godot
,向派生特质添加了从gdnative
的FromVariant
和ToVariant
默认情况下,这两个功能都是禁用的。如果您想让这个库包含对其他库的支持,请提交一个issue并告诉我。我非常乐意添加更多对游戏引擎的支持,因为这个库是专为游戏设计的。
内部表示
十进制数的内部表示如下:Decimal::from_components(sign, layer, mag)
== sign * 10^10^10^...(layer times) mag
。因此,层0的数字就是 sign * mag
,层1的数字是 sign * 10^mag
,层2的数字是 sign * 10^10^mag
,以此类推。
如果 layer > 0
和 mag < 0.0
,则数字的指数为负,例如 sign * 10^-10^10^10^ ... mag
。
sign
的值为 -1、0 或 1layer
是一个非负整数mag
是一个f64
,按照以下方式规范化:如果它大于 1e15,则对它取以 10 为底的对数并增加layer
。如果它小于log10(9e15)
(约 15.954)并且layer > 0
,则对它取 10 的幂并减少layer
。在layer 为 0 时,从负的
mags
中提取符号。零(sign == 0 || (mag == 0.0 && layer == 0)
)在所有字段中变为0, 0, 0
。
Decimal 实现了 Copy
和 Clone
,因此可以安全地引用而不必担心。
创建 Decimal
您可以使用 Decimal::from_number(f64)
、Decimal::try_from(&str)
或手动使用 Decimal::from_components(sign, layer, mag)
或 Decimal::from_mantissa_exponent(mantissa, exponent)
来创建 Decimal。
如果您使用结构体初始化语法,请确保运行 normalize()
函数以规范化 Decimal。
接受的字符串表示形式
M === M
eX === 10^X
MeX === M*10^X
eXeY === 10^(XeY)
MeXeY === M*10^(XeY)
eeX === 10^10^X
eeXeY === 10^10^(XeY)
eeeX === 10^10^10^X
eeeXeY === 10^10^10^(XeY)
eeee... (N es) X === 10^10^10^ ... (N 10^s) X
(e^N)X === 10^10^10^ ... (N 10^s) X
N PT X === 10^10^10^ ... (N 10^s) X
N PT (X) === 10^10^10^ ... (N 10^s) X
NpX === 10^10^10^ ... (N 10^s) X
X^Y === X^Y
X^^N === X^X^X^ ... (N X^s) 1
X^^N;Y === X^X^X^ ... (N X^s) Y
X^^^N === X^^X^^X^^ ... (N X^^s) 1
X^^^N;Y === X^^X^^X^^ ... (N X^^s) Y
操作
得益于Rust特质的强大功能,您可以使用常规运算符(+
、-
、*
、/
、%
、+=
、-=
、*=
、/=
、%=
)进行数学运算,以及其他数学函数,例如:abs, neg, round, floor, ceil, trunc, recip, cmp, cmpabs, max, min, maxabs, minabs, log, log10, ln, pow, root, factorial, gamma, exp, sqrt, tetrate, iteratedexp, iteratedlog, layer_add_10, layer_add, slog, ssqrt, lambertw, pentate
)。
相等性以特殊方式处理,如果两边的值都是NaN或无穷大,则它们相等。除此之外,十进制数字在1e-10
的精度上被认为是相等的。
如上所示,模运算符也得到正确实现,应该与其他运算一样准确。
另一个简洁的特性是针对所有原始数字类型的运算符实现,这意味着您可以像这样进行加法操作:Decimal::from_number(1.0) + 2.0
。转换也以相同的方式进行,任何原始数字类型都可以使用from()
和into()
转换为十进制。
关于bug的注意事项
尽管我移植了这个库,但我对数学不太了解。事实上,我对如何正确应用像幂次方、超对数等东西毫无头绪。所以,如果您发现这些函数有任何问题,您可能需要向我解释我需要更改代码中的哪些部分。
我知道这并不太专业,但我缺乏时间去获得数学学位或进一步学习这个主题。这个crate几乎是出于必要性而诞生的,因为我想要在我的游戏中实现这些功能。
除此之外,所有其他类型的bug都受欢迎。
后记
这个crate的移植花了很长时间。主要是因为它确实是一个庞大的库。作为一个单打独斗的人,未来对break_eternity.js
的更改移植也可能需要一段时间。
如果您有任何改进,请考虑贡献并积极提交pull请求。这将非常有帮助。
肯定会存在bug,尽管我非常愿意修复它们。
此外,如果您喜欢这个库,为什么不在这里给它一个星号,并在Patashu的break_eternity.js上留下评论?这将有助于提高我们包的知名度。
特别感谢
- Patashu(为他花费时间编写这个巨大的库)
- 纳鲁约科(用于OmegaNum.js的模实现,我毫不羞愧地复制了它)
依赖项
~0.7–7.5MB
~50K SLoC