跳转到内容

Ada 编程/类型/delta

来自维基教科书,开放的书籍,为一个开放的世界

Ada. Time-tested, safe and secure.
Ada. 经时间考验,安全可靠。


定点类型定义了一组具有给定绝对精度的均匀间隔的值。相反,浮点数是根据相对精度进行间隔的。

绝对精度以类型的 delta 给出。定点类型有两种,普通定点和十进制定点。

对于普通定点类型,delta 为编译器提供一个提示,用于在未指定时如何选择最小值:它可以是任何不超过 delta 的 2 的整数次幂。您可以通过属性子句指定最小值为任何不超过 delta 的值。(如果编译器无法满足此最小值,则必须拒绝声明。)

对于十进制定点类型,最小值定义为 delta,而 delta 必须是十的整数次幂。(因此,您不能通过属性子句指定最小值。)

例如,如果您定义了 delta 为 0.1 的十进制定点类型,则可以准确地存储值 0.1、1.0、2.2、5.7 等。您将无法准确地存储值 0.01。相反,该值将被向下舍入为 0.0。

如果编译器接受您的定点类型定义,它保证用该类型表示的值将具有至少指定(或更高)的精度。如果编译器无法支持类型定义(例如,由于硬件限制),则会发生编译时错误。

普通定点

[编辑 | 编辑源代码]

对于普通定点,您只需定义 delta 和一个范围

delta Delta range Low .. High

delta 可以是任何实数值——例如,您可以用以下方法定义一个以弧秒为分辨率的圆

delta 1.0 / (60 * 60) range 0.0 .. 360.0

[关于定点类型有一个相当奇怪的规则:由于其内部表示方式,范围可能只到 'Last - Delta。这有点像圆——0° 和 360° 也标记相同。]

需要注意的是,在上面的示例中,使用的最小可能值不是 。编译器将选择一个更小的值,默认情况下,该值是不超过 delta 的 2 的整数次幂。在我们的示例中,这可能是 。在大多数情况下,这将提供更好的性能,但会牺牲精度。

如果您不希望这样做,并且精度确实更重要,则可以通过属性子句 'Small 选择自己的最小值。

type Angle is delta Pi/2.0**31 range -Pi .. Pi;
for Angle'Small use Pi/2.0**31;

作为内部表示,您将获得一个 32 位有符号整数类型。

十进制定点

[编辑 | 编辑源代码]

您通过定义 delta 和所需的位数来定义十进制定点

 delta Delta digits Num_Digits

Delta 必须是 10 的正或负整数次幂——否则声明是非法的。

delta 10.0**(+2) digits 12
delta 10.0**(-2) digits 12

如果您愿意,您也可以定义所需的范围

delta Delta_Value digits Num_Digits range Low .. High

普通定点类型和十进制定点类型之间的区别

[编辑 | 编辑源代码]

有一种声明“十进制”定点的替代方法:您可以声明一个普通定点,并使用 10 的整数次幂作为 'Small。以下两个声明在内部表示方面是等效的

-- decimal fixed point

type Duration is delta 10.0**(-9) digits 9;
-- ordinary fixed point

type Duration is delta 10.0**(-9) range -1.0 .. 1.0;
for Duration'Small use 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(RM F.2 [注释]),当然只适用于十进制定点,定义了十进制 Divide 通用过程。如果支持附件 F(GNAT 支持),则必须至少支持 18 位(对于定点类型没有此类规则)。
  • 静态表达式必须是十进制定点 Small 的倍数。

结论:对于一般的数值使用,应该定义一个普通的定点数(可能带有“Small”定义)。只有当你对类似 COBOL 的使用感兴趣,即明确定义的确定性十进制语义(尤其是在金融计算中,但这可能适用于除货币之外的其他情况),你才应该选择十进制定点数。

维基教科书

[编辑 | 编辑源代码]

Ada 95 参考手册

[编辑 | 编辑源代码]

Ada 2005 参考手册

[编辑 | 编辑源代码]
华夏公益教科书