--- ais/ai-00267.txt 2002/05/25 03:42:18 1.4 +++ ais/ai-00267.txt 2002/06/11 05:15:49 1.5 @@ -1,4 +1,4 @@ -!standard 4.6 (33) 02-05-10 AI95-00267/04 +!standard 4.6 (33) 02-06-07 AI95-00267/05 !standard A.5.3 (41) !class amendment 01-05-14 !status Amendment 200Y 02-05-10 @@ -55,9 +55,68 @@ conversion of X to Some_Integer. In particular, the usual float-to-integer type conversion rounding code is not necessary, as the value has already been rounded. (This applies to all of the rounding and truncation attributes -defined in A.5.3.) +defined in A.5.3, but is critical for the use of this attribute.) !example + +The following example illustrates a possible usage of this attribute to +implement the Arcsinh function (this is an excerpt of real code). This +function is implemented using polynomial approximations over small intervals. +The coefficients of the polynomial are defined in a constant table: + + type Element is + record + X : Float_Type; + C0, C1, C2, C3 : Float_Type; + end record; + + Data : constant array (Long_Integer range <>) of Element := + (7 => (16#0.1172906#E0, 16#0.116F1D00EE#E0, 16#0.FF6852006#E0, + -16#0.8A9C5782#E-1, -16#0.29C8C88A8#E0), + 8 => (16#0.13FB6A2#E0, 16#0.13F63C00DC#E0, 16#0.FF394406C#E0, + -16#0.9E676A72#E-1, -16#0.29833F8E#E0), + 9 => (16#0.1685FA#E0, 16#0.167E904#E0, 16#0.FF03D007#E0, + -16#0.B21C84C4#E-1, -16#0.2934729F8#E0), ...); + +The body of the Arcsinh function selects the proper interval by doing some +simple computation based on its argument, and loads the coefficients of the +polynomial from the above table. It then computes the value of the polynomial +at X, and returns the result. + + function Arcsinh (X : Float_Type'Base) return Float_Type'Base is + I : Integer; + Ci0, Ci1, Ci2, Ci3, Xi, Y, Z : Float_Type'Base; + begin + ... + Y := 16#1.D6978# * X * (16#38.B433# - X * (12.0 - X)); + I := Integer (Y); + Xi := Float_Type'Base (Data (I).X); + Ci0 := Float_Type'Base (Data (I).C0); + Ci1 := Float_Type'Base (Data (I).C1); + Ci2 := Float_Type'Base (Data (I).C2); + Ci3 := Float_Type'Base (Data (I).C3); + Z := X - Xi; + return Ci0 + (Z * (Ci1 + Z * (Ci2 + Z * Ci3))); + end; + +Note that the evaluation of I involves a float-to-integer conversion. If Y +happens to lie exactly between two integers, 4.6(33) requires that the +conversion round away from zero. + +However, in this instance we really don't care if the value returned by the +conversion of, say, 41.5, is 41 or 42. The polynomials at indices 41 and 42 +are, by construction, both very good approximations of the function being +computed when Y = 41.5, so we can use either of them. (It is not even +necessary for two invocations of Arcsinh to round in the same fashion: the +rounding mode may have been changed by altering some control register, but +Arcsinh will still return results within the required accuracy.) + +With the proposed amendment, the computation of I will be written: + + I := Integer (Float_Type'Machine_Rounding (Y)); + +and it will use the fastest rounding mechanism available on the underlying +hardware. !discussion

Questions? Ask the ACAA Technical Agent