Engee 文档

Engee中的定点算术

在数值计算的世界中,绝大多数任务都是使用浮点数来解决的(漂浮物32, 漂浮64`然而,在诸如微控制器、Dsp、Fpga或Asic的实际系统中,使用浮子类型可能是不希望的或不可能的。 例如,在STM32系列微控制器中,基本型号没有硬件支持。 `浮子,浮子,并且其中的浮点运算比整数运算执行得慢得多。 在这种情况下,使用定点算术(定点),其中分数值以整数格式编码,具有分数部分的预定义长度。

定点数字(定点)是一种使用普通整数和预定义比例(小数部分的位数)表示分数值的方法。 而不是资源密集型浮点算术(漂浮物32, 漂浮64),这里使用一个简单的整数格式,其中"二进制逗号"被移位一组位数。

例如,如果小数部分的长度为 ,那个数字 存储为整数值 ,因为根据重新计算内部值的公式(存储_integer)实时(real_value) 我们得到 . 公式显示内部值被保留并且等于 ,并在计算它被解释为 .

这样的算术具有以下优点
  • 更低的资源消耗(与微控制器、Fpga和Asic相关);

  • 控制精度和值范围;

  • 可预测的舍入行为footnote:common_2[*舍入*是将值减少到可接受的形式的过程,考虑到有限的小数部分(f). 由于定点数不能准确表示所有可能的小数值,因此在运算过程中,结果会根据给定策略四舍五入(例如,到最近的值或截断)。]和overflowingfootnote:common_3[*Overflow*是一个过程,如果计算结果超过给定字大小允许的限制(W)和熟悉(`S`在此类情况下,使用溢出处理策略:饱和,其中值被限制为允许的最大/最小值,或者截断或误差输出。];

  • 支援服务 代码生成器 Verilog(HDL)和C上的。

阅读文章中有关定点算术的更多信息 guide/hdl-fixed-point-arithmetic.adoc#fixed-point-arithmetic

在Engee中使用固定点

*Engee*使用自己的包与定点工作。 EngeeFixedPoint。jl,它取代了标准的Julia包 FixedPointNumbers。jl. 与经典包装不同, EngeeFixedPoint。jl 它提供了先进的功能和精确控制定点数的表示和行为,这在资源有限的系统中尤为重要,当将计算转移到 HDL,以及在精密任务。

包裹 EngeeFixedPoint。jl 它是一个标准的*Engee*包,默认情况下包含在用户环境中,因此它不需要显式调用(通过 进口/使用)在代码中。

在*Engee*中,定点数的类型如下所示:

Fixed{S, W, f, T} <: FixedPoint

哪里:

  • S -一个标志(1 -签名脚注:common[Signed-可以存储正值和负值。 例子:: Int8, Int16, 固定{1, 16, 4}.], 0 -Unsigned注:common_1[Unsigned-只能存储正值和零。 例子:: UInt8, UInt16, 固定{0, 16, 4}.]);

  • W -字的长度(分配给数字的位数);

  • f -小数部分的长度(每个小数部分的位数,比例);

  • T -定点数的整数表示类型(Int32, UInt64 等等)。

此格式允许您准确指定数字将如何存储、解释和参与计算,因为在数据处理的所有阶段都有安全的键入和清晰的行为。


为方便起见 EngeeFixedPoint。jl 它提供了几种设置固定点类型的方法,从完整的手动分配到自动输出。

S, W, f, T = 1, 25, 10, Int32

dt1 = Fixed{S, W, f, T}
dt2 = fixdt(S, W, f)
dt3 = fixdt(Fixed{S, W, f})
dt4 = fixdt(dt2)

println(dt1 == dt2 == dt3 == dt4)  # true

哪里:

  • dt1=固定{S, W, f, T} -完整的手册描述;

  • dt2=fixdt(S,W,f) -简化创建,类型 它是自动选择的;

  • dt3=fixdt(固定{S, W, f}) -获取基于现有描述的类型;

  • dt4=fixdt(dt2) -重用,从现有类型创建副本。

所有这些选项都创建相同的类型。 固定{1, 25, 10, Int32},并可根据任务使用:

  • 完整描述(dt1 当您需要控制所有参数时,这很方便。;

  • 简化的方式(dt2)适用于典型情况,并减少了代码;

  • 从类型获取类型(dt3)生成代码或键入数据时很有用;

  • 再利用(dt4)有助于使用参数化结构,而无需重新输入参数。

类型构造函数 固定

接下来,让我们来看看在*Engee*中使用固定点的具体场景。

所以,你可以直接设置类型并传递值。:

x = Fixed{1, 15, 2}(25)

结论:

fi(6.25, 1, 15, 2)

这意味着 -整数表示(存储_integer),而真正的价值(real_value)将等于 根据公式 .

固定{S, W, f}(i::T)

基于整数表示创建固定点的构造函数 固定{S, W, f}(i::T) 接受:

  • 格式参数: S (熟悉度), W (以位为单位的宽度), f (小数部分);

  • 整数值 iT (内部表示)。

S,W,f=1,15,2#有符号,15位,2小数位
i = 25
X=Fixed{S,W,f}(i)#从整数创建

结论:

菲(6.25, 1, 15, 2) # 等效表示

固定{S, W, f, T1}(i::T2)

构造函数与前一个类似,能够显式指定存储类型。 类型将根据参数自动选择。 S, W, f,无论指定 T1.

T = Int128
x = Fixed{S, W, f, T}(i) # 指示存储类型

结论:

菲(6.25, 1, 15, 2) # 结果是相同的

FixedPointNumbers的构造函数。jl

尽管使用了新包 EngeeFixedPoint。jl,它仍然具有与包的兼容性 FixedPointNumbers。jl 以支持多个构造函数。 仅支持签名类型。

支持:

  • 固定{T, f}(i::整数,_) -整数表示的构造函数。 接受类型 T 和参数 f;

  • 固定{T, f}(价值) -真实世界的值构造函数(浮子,浮子).

例子::

T = Int32
x1 = Fixed{T, f}(i, nothing) # 从整数
x2 = Fixed{T, f}(i)          # 从一个实数

结论:

6.25#第一个构造函数的结果
25.0#第二个构造函数的结果

辅助方法

创建定点数的主要方便方法是通过辅助方法 . 与构造函数不同,它们会自动确定演示参数。

x1 = fi(3.37, 0, 63, 4)        # 具有显式参数的完整格式
x2 = fi(3.37, fixdt(0, 63, 4)) # 通过数据类型
x3 = fi(3.37, 0, 63)           # 具有自动小数部分检测功能
x4 = fi(100, 1, 8, 5)          # 溢出处理演示

结论:

3.375#四舍五入调整值
true#x1和x2是相同的
3.37#带自动选择
3.96875#溢出时的饱和结果

复数

完全支持具有相同创建方法的定点复数 :

s, w, f = 1, 62, 7;
v = 2.5 - 3.21im
x1 = fi(v, s, w, f)
x2 = fi(v, fixdt(s, w, f))
x3 = fi(v, s, w)
println(x1)
println(x1 == x2)
println(x3)
println()

结论:

fi(2.5, 1, 62, 7) - fi(3.2109375, 1, 62, 7)*im
true
fi(2.5, 1, 62, 59) - fi(3.21, 1, 62, 59)*im

使用数组和矩阵

该库完全支持定点数的向量和矩阵运算。 所有操作都会保存元素类型,并自动将指定的精度参数应用于数组的所有元素。

向量资料

创建和使用一维数组。 定点参数应用于所有元素:

s, w, f = 1, 62, 7  # 有符号类型,62位,7位小数部分
v = [1, 2, 3]       # 资料来源

# 不同的创作方式:
x1 = fi(v, s, w, f)        # 指定显式参数
x2 = fi(v, fixdt(s, w, f)) # 通过数据类型
x3 = fi(v, s, w)           # 具有自动小数部分检测功能

println(x1)
println(x1 == x2)
println(x3)

结论:

Fixed{1, 62, 7}[1.0, 2.0, 3.0]
true
Fixed{1, 62, 59}[1.0, 2.0, 3.0]

复杂矩阵

全面支持多维数组中的复数:

s, w, f = 1, 62, 7
m = [im 2.5; -1.2im 25-im]

# 创造的工作方法:
x1 = fi(m, s, w, f)        # 指定显式参数
x2 = fi(m, fixdt(s, w, f)) # 通过数据类型

println(x1)
println(x1 == x2)

结论:

Complex{Fixed{1, 62, 7, Int64}}[fi(0.0, 1, 62, 7) + fi(1.0, 1, 62, 7)*im fi(2.5, 1, 62, 7) + fi(0.0, 1, 62, 7)*im; fi(0.0, 1, 62, 7) - fi(1.203125, 1, 62, 7)*im fi(25.0, 1, 62, 7) - fi(1.0, 1, 62, 7)*im]
true

基本操作和方法

它描述了处理定点数的方法,允许您确定可接受的值范围和基本属性。

边界值

方法 打字,打字打字机 它们允许您确定特定类型的固定点的最大和最小可能值。

dt = fixdt(0, 25, -2)  # 具有25位和-2小数部分的无符号类型
x = fi(1.5, dt)        # 创建固定点编号
println(typemax(x))    # 1.34217724e8是最大可表示值
println(typemin(x))    # 0.0是无符号类型的最小值。

数学运算

系统自动选择操作结果的最佳格式,保持准确性并防止溢出。 支持所有基本算术运算(加法,减法,乘法,除法):

x1 = fi(1.5, 0, 15, 3)
x2 = fi(1.5, 1, 25, 14)
y1 = x1+x2
y2 = x1-x2
y3 = x1*x2
y4 = x1/x2
println(y1)
println(y2)
println(y3)
println(y4)
println(typeof(y1))
println(typeof(y2))
println(typeof(y3))
println(typeof(y4))

println(x1 == x2)
println(x1 <= x2)
println(x1 > x2)

结论:

3.0
0.0
2.25
0.0
Fixed{1, 28, 14, Int32}
Fixed{1, 28, 14, Int32}
Fixed{1, 40, 17, Int64}
Fixed{1, 25, -11, Int32}
true
true
false

四舍五入

各种舍入策略允许您控制计算的准确性。 默认情况下,使用RoundNearestTiesUp。

x = fi(1.5, 1, 14, 3)  # 有符号,14位,3小数位
println(round(x))      # 2.0-舍入到最接近的整数(1.5→2)
println(trunc(x))      # 1.0-删除小数部分
println(ceil(x))       # 2.0-四舍五入到一个更大的整数
println(floor(x))      # 1.0-向下舍入到较小的整数

哪里:

  • 圆形 -银行四舍五入(至最接近的偶数 0.5);

  • [医] -丢弃小数部分;

  • 齐尔 -总是在大的方式;

  • 楼层 -总是在一个较小的方向。

类型转换(conversion)

与其他库交互时,转换为标准数据类型非常有用。 转换时,将舍入规则考虑在内。

x = fi(1.5, 1, 12, 4)
y1 = Int64(x)
y2 = UInt8(x)
y3 = Float64(x)
y4 = convert(fixdt(0, 5, 2), x)
println(y1)
println(y2)
println(y3)
println(y4)
println(typeof(y1))
println(typeof(y2))
println(typeof(y3))
println(typeof(y4))

结论:

1
1
1.5
1.5
Int64
UInt8
Float64
Fixed{0, 5, 2, UInt8}

结论

因此,包 EngeeFixedPoint。jl 提供以下优点:

  • 扩展型系统:

    • 完全支持有符号和无符号数字;

    • 任意位深度(任意位大小,不仅仅是8/16/32/64/128);

    • 灵活调整小数部分(包括负值和情况下 ,小数部分的长度,比单词的长度长 ).

  • 改进类型推断规则:

    • 自动定义数学运算结果的格式(+, , *, /);

    • 删除块中自动类型继承的限制 Divide/Add/Divide/Gain.

  • 依赖于平台的代码生成:

    • 目标平台的不同类型继承规则(C或Verilog);

    • 溢出128位边界时的可预测行为(与类似物不同)。

  • 高级功能:

    • 优化了数组和矩阵的工作(参见使用数组和矩阵);

    • 完全支持复数(参见复数);

    • 有效的舍入方法(round/trunk/ceiling/floor,有关详细信息,请参阅[舍入])。

    • 支持基本方法(zero/one/typemin/typemax),请参阅边界值

有用的连结