1个不稳定版本
0.1.0 | 2020年7月13日 |
---|
#437 在 嵌入式开发
55KB
1K SLoC
灵活的定点数
此crate旨在简化固定点类型的使用,尤其是在无FPU硬件上。为此,它引入了具有可使用和灵活操作的泛型固定点类型。
概述
引入的数值类型是具有三个类型参数的泛型
Radix
- 类型的基础,2表示二进制小数点,10表示十进制小数点Digits
- 有价值数字的数量,代表**尾数**Exponent
- 类型的静态**指数**值
因此,类型的值可以表示为 mantissa
× radix
exponent
。
# use ufix::{Fix, bin, dec};
# use typenum::*;
#
// Signed binary fixed with 5 bits mantissa and -3 as exponent.
// [5]*2^-3
type BF1 = Fix<P2, P5, N3>;
// or using type alias
type BF2 = bin::Fix<P5, N3>;
// Unsigned binary fixed with 5 bits mantissa and 3 as exponent.
// [5]*2^3
type BF1 = Fix<U2, P5, P3>;
// or using type alias
type BF2 = bin::UFix<P5, P3>;
// Signed decimal fixed with 12 digits mantissa and -7 as exponent.
// [12]*10^-7
type DF1 = Fix<P12, U10, N7>;
type DF2 = dec::Fix<P12, N7>;
P*
作为基数类型参数表示有符号类型。要创建无符号类型,请使用 U*
代替。
与众所周知且广泛使用的 Qn.m 表示法不同,指数不受尾数位的限制。它可以小于尾数位以表示更精确的小值。此外,它也可以大于零以表示精度较低的大值。
# use ufix::Fix;
# use typenum::*;
#
// [5]*2^-7
// 0b0.0000000 .. 0b0.0011111
type BF1 = Fix<U2, U5, N7>;
// [5]*2^7
// 0b0000000 .. 0b1111100
type BF2 = Fix<U2, U5, P7>;
定点算术在乘法中存在众所周知的溢出问题,特别是在无FPU硬件上。此外,它在除法中存在众所周知的精度损失问题。
此crate通过根据特定操作调整尾数宽度和指数值来避免溢出和精度损失。
请参阅下面的示例
use ufix::{Cast, bin::{Fix}};
use typenum::*;
let a = Fix::<P16, N8>::from(123.45);
let b = Fix::<P12, N6>::from(78.9);
// The addition without overflow
let c = a + b; // Fix<P17, N8>
assert_eq!(c, Fix::<P17, N8>::from(202.34));
use ufix::{Cast, bin::{Fix}};
use typenum::*;
let a = Fix::<P16, N8>::from(123.45);
let b = Fix::<P16, N8>::from(78.9);
// The multiplication without overflow
let c = a * b; // Fix<P32, N16>
assert_eq!(c, Fix::<P32, N16>::from(9739.95047));
use ufix::{Cast, bin::{Fix}};
use typenum::*;
let a = Fix::<P16, N8>::from(123.45);
let b = Fix::<P16, N8>::from(78.9);
// The division without precision loss
let c = Fix::<P32, N16>::cast(a) / b;
assert_eq!(c, Fix::<P16, N8>::from(1.5647));
优化技术
当您针对 FPU 无硬件以获得最佳性能并减小固件大小时,应仅使用二进制定点算术,因为内部它使用整数操作,并且指数调整操作只需要位操作。此外,当可能且不损失所需精度时,应避免超过平台字大小。
默认情况下,此crate使用32位整数作为在32位处理器上使用的最佳选择。当您针对16位或8位处理器时,通常应分别使用 _word16 或 _word8 功能。
支持的功能
此crate按设计是 no_std
。
此crate支持高达 64位 的尾数。使用 i128 功能可以启用高达 128位 的支持。
word8 和 word16 功能可以将最小尾数大小分别减少到8位和16位。默认情况下,至少使用32位字。
Fix
类型的演变
-
由 Curtis McEnroe 创建的 fix 包。
该包定义了一个简单的定点类型,支持泛型 基数 和 指数。这项工作是从 fix 的继承者开始的。
-
将
Bits
参数的意义从 尾数类型 更改为 尾数位数。为了获得更多定点类型的灵活性,我们需要知道尾数的有效位数。这样我们就可以轻松地选择操作结果的适当类型。此外,这也使得可以操作具有不同尾数和指数的操作数。
-
将
Bits
参数的意义从 尾数位数 更改为 根据基数计算的尾数位数。实际上,与数字的实际位数相比,使用二进制位数进行操作更为简单。因为位数取决于基数,所以对于二进制定点类型,它仍然是与之前相同的位数。
依赖项
~180KB