2014-02-28 92 views
2

在Ada中聲明範圍始終包含在內。 如果我想具有所有從042整數a型(或作爲工科數學間隔:[0, 42])我聲明,如下所示:我如何在ada中聲明一個非包含浮點範圍?

type zero_to_42 is range 0 .. 42; 

如果我要排除的零(範圍(0, 42]),這不是離散類型的問題:

type not_zero_to_42 is range (zero_to_42'First + 1) .. zero_to_42'Last; 

,但我仍然需要手工做到這一點,沒有zero_to_answer'NextAfterFirst

對於浮點類型的我不知道如何正確地做到這一點。排除零很簡單,但排除其他任何東西似乎實現定義給我。

type works is digits 6 range 0.0 .. 42.0 
type also_works is new works range (0.0 + works'small) .. 42.0 
type broken is new works range 0.0 .. (42.0 - works'small) 

因爲附近42.0浮點值比浮附近0.0點值精度要求不高,42.0 - works'small四捨五入爲42.0 我當然可以通過手的作品(如41.9999)找到一個值,但似乎醜陋的我,當我更改works所具有的位數時可能無法工作。

+0

我不認爲語言爲浮點類型定義了'small';該屬性用於定點。允許實現者定義自己的屬性,但我不確定是否允許他們在語言未定義的地方定義語言定義的屬性。無論如何,在浮點類型上使用''small'似乎給出了實現定義的結果,並且不具有可移植性。 – ajb

+0

@ajb正確地說'小,但是有浮動點類型的Fraction屬性。也允許實現添加新的(非標準)屬性,但它們必須在用戶指南中記錄。可以使用編譯指示(不記得哪一個)來禁止實現定義的屬性。 – darkestkhan

+0

@darkestkhan(1)一個正數的'Fraction'總是返回一個0.5到1之間的結果,所以這裏不適合。 (2)RM 4.1.4(12)表示,新屬性通常不能與語言定義的標識符具有相同的標識符,因此除非在Ada 83中定義,否則實現不應定義自己的「small」。 3)'雜注限制(No_Implementation_Attributes)'是你正在尋找的。 – ajb

回答

1

'Succ'Pred屬性可用於浮點值以返回下一個或上一個機器編號。如果T是浮點型,

T'Succ(X) 

是最小的浮點「機號」 > X,並且

T'Pred(X) 

是最大的浮點機器數< X。因此:

type Works is digits 6 range 0.0 .. 42.0; 
subtype Exclusive is Works range 0.0 .. Works'Pred(42.0); 

或者(因爲在type聲明的範圍可能不相關):

type Digits_6 is digits 6; 
subtype Exclusive is Digits_6 range 0.0 .. Digits_6'Pred(42.0); 

或者

type Exclusive is digits 6 range 0.0 .. Float'Pred(42.0); 

假設你知道Float是一個32位IEEE浮點和Exclusive也將是其中之一。

2

什麼都可以在這裏使用的是'Adjacent(near_value, towards_value)

type works is digits 6 range 0.0 .. 42.0 
type also_works is new works range (0.0 + works'small) .. 42.0 
type still_works is new works range 0.0 .. works'Adjacent(42.0, 0.0) 

這個打印出來still_works'lastworks'last時查找哪個值可以由處於towards_value

方向最接近near_value機器表示很可能結果看起來/是相同的,但比較這兩個將不起作用

declare 
    type works is digits 6 range 0.0 .. 42.0 
    subtype still_works is works range 0.0 .. works'Adjacent(42.0, 0.0) 
begin 
    Text_IO.Put_Line(works'Image(works'Last)); 
    Text_IO.Put_Line(still_works'Image(still_works'Last)); 
    Text_IO.Put_Line(Boolean'Image(works'Last = still_works'Last)); 
end; 
當蚊蚋編譯個

產量:

4.20000E+01 
4.20000E+01 
FALSE 
+2

我認爲'works'Pred(42.0)'應該是等價的,雖然'Adjacent'可能會使意圖更清晰。 – ajb

+0

''Pred'和'Succ'是我一直在尋找的!謝謝!如果你添加一個答案,我會選擇它作爲正確的答案。 –

1

您可能能夠使用艾達2012動態謂詞:

type Exclusive is new Float range 0.0 .. 42.0 
    with Dynamic_Predicate => Exclusive > 0.0 and then Exclusive < 42.0; 

但GNAT似乎與此煩惱:GCC 4.8.1是確定的, GNAT GPL 2013甚至不會接受1.0或41.0的值,並且GCC 4.9.0-20140119會拋出一個錯誤框!