cxg2004.a
来自「用于进行gcc测试」· A 代码 · 共 500 行 · 第 1/2 页
A
500 行
-- Evenly distributed selection of arguments Ran := Real (I) / Real (Number_Samples); -- make sure x and x/3 are both exactly representable -- on the machine. See "Implementation and Testing of -- Function Software" page 44. X := (B - A) * Ran + A; Y := Real'Leading_Part ( X/3.0, Real'Machine_Mantissa - Real'Exponent (3.0) ); X := Y * 3.0; Actual := Cos (X); ZZ := Cos(Y); Expected := ZZ * (4.0 * ZZ * ZZ - 3.0); -- note that since the expected value is computed, we -- must take the error in that computation into account. -- See Cody pp 141-143. MRE := 6.0; Check (Actual, Expected, "cos test of range" & Arg_Range & Integer'Image (I), MRE); exit when Accuracy_Error_Reported; end loop; exception when Constraint_Error => Report.Failed ("Constraint_Error raised in cos check"); when others => Report.Failed ("exception in cos check"); end Cos_Check; procedure Special_Angle_Checks is type Data_Point is record Degrees, Radians, Sine, Cosine : Real; Sin_Result_Error, Cos_Result_Error : Boolean; end record; type Test_Data_Type is array (Positive range <>) of Data_Point; -- the values in the following table only involve static -- expressions to minimize any loss of precision. However, -- there are two sources of error that must be accounted for -- in the following tests. -- First, when a cycle is not specified there can be a roundoff -- error in the value of Pi used. This error does not apply -- when a cycle of 2.0 * Pi is explicitly provided. -- Second, the expected results that involve sqrt values also -- have a potential roundoff error. -- The amount of error due to error in the argument is computed -- as follows: -- sin(x+err) = sin(x)*cos(err) + cos(x)*sin(err) -- ~= sin(x) + err * cos(x) -- similarly for cos the error due to error in the argument is -- computed as follows: -- cos(x+err) = cos(x)*cos(err) - sin(x)*sin(err) -- ~= cos(x) - err * sin(x) -- In both cases the term "err" is bounded by 0.5 * argument. Test_Data : constant Test_Data_Type := (-- degrees radians sine cosine sin_er cos_er test # ( 0.0, 0.0, 0.0, 1.0, False, False ), -- 1 ( 30.0, Pi/6.0, 0.5, Sqrt3/2.0, False, True ), -- 2 ( 60.0, Pi/3.0, Sqrt3/2.0, 0.5, True, False ), -- 3 ( 90.0, Pi/2.0, 1.0, 0.0, False, False ), -- 4 (120.0, 2.0*Pi/3.0, Sqrt3/2.0, -0.5, True, False ), -- 5 (150.0, 5.0*Pi/6.0, 0.5, -Sqrt3/2.0, False, True ), -- 6 (180.0, Pi, 0.0, -1.0, False, False ), -- 7 (210.0, 7.0*Pi/6.0, -0.5, -Sqrt3/2.0, False, True ), -- 8 (240.0, 8.0*Pi/6.0, -Sqrt3/2.0, -0.5, True, False ), -- 9 (270.0, 9.0*Pi/6.0, -1.0, 0.0, False, False ), -- 10 (300.0, 10.0*Pi/6.0, -Sqrt3/2.0, 0.5, True, False ), -- 11 (330.0, 11.0*Pi/6.0, -0.5, Sqrt3/2.0, False, True ), -- 12 (360.0, 2.0*Pi, 0.0, 1.0, False, False ), -- 13 ( 45.0, Pi/4.0, Sqrt2/2.0, Sqrt2/2.0, True, True ), -- 14 (135.0, 3.0*Pi/4.0, Sqrt2/2.0, -Sqrt2/2.0, True, True ), -- 15 (225.0, 5.0*Pi/4.0, -Sqrt2/2.0, -Sqrt2/2.0, True, True ), -- 16 (315.0, 7.0*Pi/4.0, -Sqrt2/2.0, Sqrt2/2.0, True, True ), -- 17 (405.0, 9.0*Pi/4.0, Sqrt2/2.0, Sqrt2/2.0, True, True ) ); -- 18 Y : Real; Sin_Arg_Err, Cos_Arg_Err, Sin_Result_Err, Cos_Result_Err : Real; begin for I in Test_Data'Range loop -- compute error components Sin_Arg_Err := abs Test_Data (I).Cosine * abs Test_Data (I).Radians / 2.0; Cos_Arg_Err := abs Test_Data (I).Sine * abs Test_Data (I).Radians / 2.0; if Test_Data (I).Sin_Result_Error then Sin_Result_Err := 0.5; else Sin_Result_Err := 0.0; end if; if Test_Data (I).Cos_Result_Error then Cos_Result_Err := 1.0; else Cos_Result_Err := 0.0; end if; Y := Sin (Test_Data (I).Radians); Check (Y, Test_Data (I).Sine, "test" & Integer'Image (I) & " sin(r)", 2.0 + Sin_Arg_Err + Sin_Result_Err); Y := Cos (Test_Data (I).Radians); Check (Y, Test_Data (I).Cosine, "test" & Integer'Image (I) & " cos(r)", 2.0 + Cos_Arg_Err + Cos_Result_Err); Y := Sin (Test_Data (I).Degrees, 360.0); Check (Y, Test_Data (I).Sine, "test" & Integer'Image (I) & " sin(d,360)", 2.0 + Sin_Result_Err); Y := Cos (Test_Data (I).Degrees, 360.0); Check (Y, Test_Data (I).Cosine, "test" & Integer'Image (I) & " cos(d,360)", 2.0 + Cos_Result_Err); --pwb-math Y := Sin (Test_Data (I).Radians, 2.0*Pi);--pwb-math Check (Y, Test_Data (I).Sine,--pwb-math "test" & Integer'Image (I) & " sin(r,2pi)",--pwb-math 2.0 + Sin_Result_Err); --pwb-math Y := Cos (Test_Data (I).Radians, 2.0*Pi);--pwb-math Check (Y, Test_Data (I).Cosine,--pwb-math "test" & Integer'Image (I) & " cos(r,2pi)",--pwb-math 2.0 + Cos_Result_Err); end loop; exception when Constraint_Error => Report.Failed ("Constraint_Error raised in special angle test"); when others => Report.Failed ("exception in special angle test"); end Special_Angle_Checks; -- check the rule of A.5.1(41);6.0 which requires that the -- result be exact if the mathematical result is 0.0, 1.0, -- or -1.0 procedure Exact_Result_Checks is type Data_Point is record Degrees, Sine, Cosine : Real; end record; type Test_Data_Type is array (Positive range <>) of Data_Point; Test_Data : constant Test_Data_Type := ( -- degrees sine cosine test # ( 0.0, 0.0, 1.0 ), -- 1 ( 90.0, 1.0, 0.0 ), -- 2 (180.0, 0.0, -1.0 ), -- 3 (270.0, -1.0, 0.0 ), -- 4 (360.0, 0.0, 1.0 ), -- 5 ( 90.0 + 360.0, 1.0, 0.0 ), -- 6 (180.0 + 360.0, 0.0, -1.0 ), -- 7 (270.0 + 360.0,-1.0, 0.0 ), -- 8 (360.0 + 360.0, 0.0, 1.0 ) ); -- 9 Y : Real; begin for I in Test_Data'Range loop Y := Sin (Test_Data(I).Degrees, 360.0); if Y /= Test_Data(I).Sine then Report.Failed ("exact result for sin(" & Real'Image (Test_Data(I).Degrees) & ", 360.0) is not" & Real'Image (Test_Data(I).Sine) & " Difference is " & Real'Image (Y - Test_Data(I).Sine) ); end if; Y := Cos (Test_Data(I).Degrees, 360.0); if Y /= Test_Data(I).Cosine then Report.Failed ("exact result for cos(" & Real'Image (Test_Data(I).Degrees) & ", 360.0) is not" & Real'Image (Test_Data(I).Cosine) & " Difference is " & Real'Image (Y - Test_Data(I).Cosine) ); end if; end loop; exception when Constraint_Error => Report.Failed ("Constraint_Error raised in exact result check"); when others => Report.Failed ("exception in exact result check"); end Exact_Result_Checks; procedure Do_Test is begin Special_Angle_Checks; Sin_Check (0.0, Pi/2.0, "0..pi/2"); Sin_Check (6.0*Pi, 6.5*Pi, "6pi..6.5pi"); Cos_Check (7.0*Pi, 7.5*Pi, "7pi..7.5pi"); Exact_Result_Checks; end Do_Test; end Generic_Check; ----------------------------------------------------------------------- ----------------------------------------------------------------------- package Float_Check is new Generic_Check (Float); -- check the floating point type with the most digits type A_Long_Float is digits System.Max_Digits; package A_Long_Float_Check is new Generic_Check (A_Long_Float); ----------------------------------------------------------------------- -----------------------------------------------------------------------begin Report.Test ("CXG2004", "Check the accuracy of the sin and cos functions"); if Verbose then Report.Comment ("checking Standard.Float"); end if; Float_Check.Do_Test; if Verbose then Report.Comment ("checking a digits" & Integer'Image (System.Max_Digits) & " floating point type"); end if; A_Long_Float_Check.Do_Test; Report.Result;end CXG2004;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?