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 和一個範圍
deltaDeltarangeLow .. High
delta 可以是任何實數值——例如,您可以用以下方法定義一個以弧秒為解析度的圓
delta1.0 / (60 * 60)range0.0 .. 360.0
[關於定點型別有一個相當奇怪的規則:由於其內部表示方式,範圍可能只到 'Last - Delta。這有點像圓——0° 和 360° 也標記相同。]
需要注意的是,在上面的示例中,使用的最小可能值不是 。編譯器將選擇一個更小的值,預設情況下,該值是不超過 delta 的 2 的整數次冪。在我們的示例中,這可能是 。在大多數情況下,這將提供更好的效能,但會犧牲精度。
如果您不希望這樣做,並且精度確實更重要,則可以透過屬性子句 'Small 選擇自己的最小值。
typeAngleisdeltaPi/2.0**31range-Pi .. Pi;forAngle'SmallusePi/2.0**31;
作為內部表示,您將獲得一個 32 位有符號整數型別。
您透過定義 delta 和所需的位數來定義十進位制定點
deltaDeltadigitsNum_Digits
Delta 必須是 10 的正或負整數次冪——否則宣告是非法的。
delta10.0**(+2)digits12delta10.0**(-2)digits12
如果您願意,您也可以定義所需的範圍
deltaDelta_ValuedigitsNum_DigitsrangeLow .. High
有一種宣告“十進位制”定點的替代方法:您可以宣告一個普通定點,並使用 10 的整數次冪作為 'Small。以下兩個宣告在內部表示方面是等效的
-- decimal fixed pointtypeDurationisdelta10.0**(-9)digits9;
-- ordinary fixed pointtypeDurationisdelta10.0**(-9)range-1.0 .. 1.0;forDuration'Smalluse10.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 位(對於定點型別沒有此類規則)。
- Decimal_IO(RM A.10.1: (73) [註釋])的語義不同於 Fixed_IO(RM A.10.1: (68) [註釋])。
- 靜態表示式必須是十進位制定點 Small 的倍數。
結論:對於一般的數值使用,應該定義一個普通的定點數(可能帶有“Small”定義)。只有當你對類似 COBOL 的使用感興趣,即明確定義的確定性十進位制語義(尤其是在金融計算中,但這可能適用於除貨幣之外的其他情況),你才應該選擇十進位制定點數。
