Ada 编程/类型/delta
定点类型定义了一组具有给定绝对精度的均匀间隔的值。相反,浮点数是根据相对精度进行间隔的。
绝对精度以类型的 delta 给出。定点类型有两种,普通定点和十进制定点。
对于普通定点类型,delta 为编译器提供一个提示,用于在未指定时如何选择最小值:它可以是任何不超过 delta 的 2 的整数次幂。您可以通过属性子句指定最小值为任何不超过 delta 的值。(如果编译器无法满足此最小值,则必须拒绝声明。)
对于十进制定点类型,最小值定义为 delta,而 delta 必须是十的整数次幂。(因此,您不能通过属性子句指定最小值。)
例如,如果您定义了 delta 为 0.1 的十进制定点类型,则可以准确地存储值 0.1、1.0、2.2、5.7 等。您将无法准确地存储值 0.01。相反,该值将被向下舍入为 0.0。
如果编译器接受您的定点类型定义,它保证用该类型表示的值将具有至少指定(或更高)的精度。如果编译器无法支持类型定义(例如,由于硬件限制),则会发生编译时错误。
对于普通定点,您只需定义 delta 和一个范围
delta
Deltarange
Low .. High
delta 可以是任何实数值——例如,您可以用以下方法定义一个以弧秒为分辨率的圆
delta
1.0 / (60 * 60)range
0.0 .. 360.0
[关于定点类型有一个相当奇怪的规则:由于其内部表示方式,范围可能只到 'Last - Delta
。这有点像圆——0° 和 360° 也标记相同。]
需要注意的是,在上面的示例中,使用的最小可能值不是 。编译器将选择一个更小的值,默认情况下,该值是不超过 delta 的 2 的整数次幂。在我们的示例中,这可能是 。在大多数情况下,这将提供更好的性能,但会牺牲精度。
如果您不希望这样做,并且精度确实更重要,则可以通过属性子句 'Small 选择自己的最小值。
type
Angleis
delta
Pi/2.0**31range
-Pi .. Pi;for
Angle'Smalluse
Pi/2.0**31;
作为内部表示,您将获得一个 32 位有符号整数类型。
您通过定义 delta 和所需的位数来定义十进制定点
delta
Deltadigits
Num_Digits
Delta 必须是 10 的正或负整数次幂——否则声明是非法的。
delta
10.0**(+2)digits
12delta
10.0**(-2)digits
12
如果您愿意,您也可以定义所需的范围
delta
Delta_Valuedigits
Num_Digitsrange
Low .. High
有一种声明“十进制”定点的替代方法:您可以声明一个普通定点,并使用 10 的整数次幂作为 'Small。以下两个声明在内部表示方面是等效的
-- decimal fixed pointtype
Durationis
delta
10.0**(-9)digits
9;
-- ordinary fixed pointtype
Durationis
delta
10.0**(-9)range
-1.0 .. 1.0;for
Duration'Smalluse
10.0**(-9);
您可能想知道这两个声明之间有什么区别。答案是
在精度、加法、减法、与整数值的乘法方面没有区别。
以下是普通定点类型和十进制定点类型之间差异的不完整列表。
- 十进制定点类型旨在反映具有给定位数的典型COBOL声明。
- 在乘法和除法(RM 4.5.5: (21) [注释])和类型转换中,十进制定点需要截断,而普通定点则不需要。对十进制定点的操作是完全指定的,而对于普通定点则不是。
- 以下属性仅针对十进制定点定义:T'Digits(RM 3.5.10: (10) [注释])对应于可表示的小数位数;T'Scale(RM 3.5.10: (11) [注释],取自COBOL)指示点相对于最右边的有效位的位置;T'Round(RM 3.5.10: (12) [注释])可用于指定转换时的舍入。
- Decimal_IO(RM A.10.1: (73) [注释])的语义不同于 Fixed_IO(RM A.10.1: (68) [注释])。
- 静态表达式必须是十进制定点 Small 的倍数。
结论:对于一般的数值使用,应该定义一个普通的定点数(可能带有“Small”定义)。只有当你对类似 COBOL 的使用感兴趣,即明确定义的确定性十进制语义(尤其是在金融计算中,但这可能适用于除货币之外的其他情况),你才应该选择十进制定点数。