1-- CXA5A10.A 2-- 3-- Grant of Unlimited Rights 4-- 5-- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687, 6-- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained 7-- unlimited rights in the software and documentation contained herein. 8-- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making 9-- this public release, the Government intends to confer upon all 10-- recipients unlimited rights equal to those held by the Government. 11-- These rights include rights to use, duplicate, release or disclose the 12-- released technical data and computer software in whole or in part, in 13-- any manner and for any purpose whatsoever, and to have or permit others 14-- to do so. 15-- 16-- DISCLAIMER 17-- 18-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR 19-- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED 20-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE 21-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE 22-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A 23-- PARTICULAR PURPOSE OF SAID MATERIAL. 24--* 25-- 26-- OBJECTIVE: 27-- Check that the functions Exp and Sqrt, and the exponentiation 28-- operator "**" provide correct results. 29-- 30-- TEST DESCRIPTION: 31-- This test examines both the versions of Exp, Sqrt, and "**" 32-- resulting from the instantiation of the 33-- Ada.Numerics.Generic_Elementary_Functions with a type derived from 34-- type Float, as well as the preinstantiated version of this package 35-- for type Float. 36-- Prescribed results (stated as such in the reference manual), 37-- including instances prescribed to raise exceptions, are examined 38-- in the test cases. In addition, certain evaluations are performed 39-- for the preinstantiated package where the actual function result is 40-- compared with the expected result (within an epsilon range of 41-- accuracy). 42-- 43-- TEST FILES: 44-- The following files comprise this test: 45-- 46-- FXA5A00.A (foundation code) 47-- CXA5A10.A 48-- 49-- 50-- CHANGE HISTORY: 51-- 17 Apr 95 SAIC Initial prerelease version. 52-- 13 Jun 95 SAIC Incorporated use of Dont_Optimize procedure, and 53-- use of Result_Within_Range function overloaded for 54-- FXA5A00.New_Float_Type. 55-- 18 Apr 96 SAIC Incorporated reviewer comments for ACVC 2.1. 56-- 01 Oct 01 RLB Protected Constraint_Error exception tests by 57-- first testing for 'Machine_Overflows. 58-- 59--! 60 61with Ada.Exceptions; 62with Ada.Numerics.Elementary_Functions; 63with Ada.Numerics.Generic_Elementary_Functions; 64with FXA5A00; 65with Report; 66 67procedure CXA5A10 is 68begin 69 70 Report.Test ("CXA5A10", "Check that Exp, Sqrt, and the ""**"" operator " & 71 "provide correct results"); 72 73 Test_Block: 74 declare 75 76 use FXA5A00, Ada.Numerics; 77 use Ada.Exceptions; 78 79 package GEF is new Ada.Numerics.Generic_Elementary_Functions(New_Float); 80 package EF renames Ada.Numerics.Elementary_Functions; 81 82 use GEF, EF; 83 84 Arg, 85 Float_Result : Float; 86 New_Float_Result : New_Float; 87 88 Flag_1, Flag_2, Flag_3, Flag_4, 89 Incorrect_Inverse_Base_e, 90 Incorrect_Inverse_Base_2, 91 Incorrect_Inverse_Base_8, 92 Incorrect_Inverse_Base_10, 93 Incorrect_Inverse_Base_16 : Boolean := False; 94 95 procedure Dont_Optimize_Float is new Dont_Optimize(Float); 96 procedure Dont_Optimize_New_Float is new Dont_Optimize(New_Float); 97 98 begin 99 100 -- Testing of the "**" operator, both instantiated and pre-instantiated 101 -- version. 102 103 -- Check that Argument_Error is raised by the exponentiation operator 104 -- when the value of the Left parameter (operand) is negative. 105 106 begin 107 New_Float_Result := GEF."**"(Left => -10.0, 108 Right => 2.0); 109 Report.Failed("Argument_Error not raised by the instantiated " & 110 "version of the exponentiation operator when the " & 111 "value of the Left parameter is negative"); 112 Dont_Optimize_New_Float(New_Float_Result, 1); 113 exception 114 when Argument_Error => null; -- OK, expected exception. 115 when others => 116 Report.Failed("Unexpected exception raised by the " & 117 "instantiated version of the exponentiation " & 118 "operator when the value of the Left parameter " & 119 "is negative"); 120 end; 121 122 begin 123 Float_Result := (-FXA5A00.Small) ** 4.0; 124 Report.Failed("Argument_Error not raised by the preinstantiated " & 125 "version of the exponentiation operator when the " & 126 "value of the Left parameter is negative"); 127 Dont_Optimize_Float(Float_Result, 2); 128 exception 129 when Argument_Error => null; -- OK, expected exception. 130 when others => 131 Report.Failed("Unexpected exception raised by the " & 132 "preinstantiated version of the exponentiation " & 133 "operator when the value of the Left parameter " & 134 "is negative"); 135 end; 136 137 138 -- Check that Argument_Error is raised by the exponentiation operator 139 -- when both parameters (operands) have the value 0.0. 140 141 begin 142 New_Float_Result := GEF."**"(0.0, Right => 0.0); 143 Report.Failed("Argument_Error not raised by the instantiated " & 144 "version of the exponentiation operator when " & 145 "both operands are zero"); 146 Dont_Optimize_New_Float(New_Float_Result, 3); 147 exception 148 when Argument_Error => null; -- OK, expected exception. 149 when others => 150 Report.Failed("Unexpected exception raised by the " & 151 "instantiated version of the exponentiation " & 152 "operator when both operands are zero"); 153 end; 154 155 begin 156 Float_Result := 0.0**0.0; 157 Report.Failed("Argument_Error not raised by the preinstantiated " & 158 "version of the exponentiation operator when both " & 159 "operands are zero"); 160 Dont_Optimize_Float(Float_Result, 4); 161 exception 162 when Argument_Error => null; -- OK, expected exception. 163 when others => 164 Report.Failed("Unexpected exception raised by the " & 165 "preinstantiated version of the exponentiation " & 166 "operator when both operands are zero"); 167 end; 168 169 170 -- Check that Constraint_Error is raised by the exponentiation 171 -- operator when the value of the left parameter (operand) is zero, 172 -- and the value of the right parameter (exponent) is negative. 173 -- This check applies only if Machine_Overflows is true [A.5.1(28, 30)]. 174 175 if New_Float'Machine_Overflows = True then 176 begin 177 New_Float_Result := GEF."**"(0.0, Right => -2.0); 178 Report.Failed("Constraint_Error not raised by the instantiated " & 179 "version of the exponentiation operator when " & 180 "the left parameter is 0.0, and the right " & 181 "parameter is negative"); 182 Dont_Optimize_New_Float(New_Float_Result, 5); 183 exception 184 when Constraint_Error => null; -- OK, expected exception. 185 when others => 186 Report.Failed("Unexpected exception raised by the " & 187 "instantiated version of the exponentiation " & 188 "operator when the left parameter is 0.0, " & 189 "and the right parameter is negative"); 190 end; 191 end if; 192 193 if Float'Machine_Overflows = True then 194 begin 195 Float_Result := 0.0 ** (-FXA5A00.Small); 196 Report.Failed("Constraint_Error not raised by the " & 197 "preinstantiated version of the exponentiation " & 198 "operator when the left parameter is 0.0, and the " & 199 "right parameter is negative"); 200 Dont_Optimize_Float(Float_Result, 6); 201 exception 202 when Constraint_Error => null; -- OK, expected exception. 203 when others => 204 Report.Failed("Unexpected exception raised by the " & 205 "preinstantiated version of the exponentiation " & 206 "operator when the left parameter is 0.0, and " & 207 "the right parameter is negative"); 208 end; 209 end if; 210 211 -- Prescribed results. 212 -- Check that exponentiation by a 0.0 exponent yields the value one. 213 214 if GEF."**"(Left => 10.0, Right => 0.0) /= 1.0 or 215 EF."**"(FXA5A00.Large, Right => 0.0) /= 1.0 or 216 GEF."**"(3.0, 0.0) /= 1.0 or 217 FXA5A00.Small ** 0.0 /= 1.0 218 then 219 Report.Failed("Incorrect results returned from the ""**"" " & 220 "operator when the value of the exponent is 0.0"); 221 end if; 222 223 224 -- Check that exponentiation by a unit exponent yields the value 225 -- of the left operand. 226 227 if GEF."**"(Left => 50.0, Right => 1.0) /= 50.0 or 228 EF."**"(FXA5A00.Large, Right => 1.0) /= FXA5A00.Large or 229 GEF."**"(6.0, 1.0) /= 6.0 or 230 FXA5A00.Small ** 1.0 /= FXA5A00.Small 231 then 232 Report.Failed("Incorrect results returned from the ""**"" " & 233 "operator when the value of the exponent is 1.0"); 234 end if; 235 236 237 -- Check that exponentiation of the value 1.0 yields the value 1.0. 238 239 if GEF."**"(Left => 1.0, Right => 16.0) /= 1.0 or 240 EF."**"(1.0, Right => FXA5A00.Large) /= 1.0 or 241 GEF."**"(1.0, 3.0) /= 1.0 or 242 1.0 ** FXA5A00.Small /= 1.0 243 then 244 Report.Failed("Incorrect results returned from the ""**"" " & 245 "operator when the value of the operand is 1.0"); 246 end if; 247 248 249 -- Check that exponentiation of the value 0.0 yields the value 0.0. 250 251 if GEF."**"(Left => 0.0, Right => 10.0) /= 0.0 or 252 EF."**"(0.0, Right => FXA5A00.Large) /= 0.0 or 253 GEF."**"(0.0, 4.0) /= 0.0 or 254 0.0 ** FXA5A00.Small /= 0.0 255 then 256 Report.Failed("Incorrect results returned from the ""**"" " & 257 "operator when the value of the operand is 0.0"); 258 end if; 259 260 261 -- Check that exponentiation of various operands with a variety of 262 -- of exponent values yield correct results. 263 264 if not Result_Within_Range(GEF."**"(5.0, 2.0), 25.0, 0.01) or 265 not Result_Within_Range(GEF."**"(1.225, 1.5), 1.36, 0.01) or 266 not Result_Within_Range(GEF."**"(0.26, 2.0), 0.068, 0.001) or 267 not Result_Within_Range( EF."**"(e, 5.0), 148.4, 0.1) or 268 not Result_Within_Range( EF."**"(10.0, e), 522.7, 0.1) or 269 not Result_Within_Range( EF."**"(e, (-3.0)), 0.050, 0.001) or 270 not Result_Within_Range(GEF."**"(10.0,(-2.0)), 0.010, 0.001) 271 then 272 Report.Failed("Incorrect results returned from the ""**"" " & 273 "operator with a variety of operand and exponent " & 274 "values"); 275 end if; 276 277 278 -- Use the following loops to check for internal consistency between 279 -- inverse functions. 280 281 declare 282 -- Use the relative error value to account for non-exact 283 -- computations. 284 TC_Relative_Error: Float := 0.005; 285 begin 286 for i in 1..5 loop 287 for j in 0..5 loop 288 if not Incorrect_Inverse_Base_e and 289 not FXA5A00.Result_Within_Range 290 (Float(i)**Float(j), 291 e**(Float(j)*EF.Log(Float(i))), 292 TC_Relative_Error) 293 then 294 Incorrect_Inverse_Base_e := True; 295 Report.Failed("Incorrect Log-** Inverse calc for Base e " & 296 "with i= " & Integer'Image(i) & " and j= " & 297 Integer'Image(j)); 298 end if; 299 if not Incorrect_Inverse_Base_2 and 300 not FXA5A00.Result_Within_Range 301 (Float(i)**Float(j), 302 2.0**(Float(j)*EF.Log(Float(i),2.0)), 303 TC_Relative_Error) 304 then 305 Incorrect_Inverse_Base_2 := True; 306 Report.Failed("Incorrect Log-** Inverse calc for Base 2 " & 307 "with i= " & Integer'Image(i) & " and j= " & 308 Integer'Image(j)); 309 end if; 310 if not Incorrect_Inverse_Base_8 and 311 not FXA5A00.Result_Within_Range 312 (Float(i)**Float(j), 313 8.0**(Float(j)*EF.Log(Float(i),8.0)), 314 TC_Relative_Error) 315 then 316 Incorrect_Inverse_Base_8 := True; 317 Report.Failed("Incorrect Log-** Inverse calc for Base 8 " & 318 "with i= " & Integer'Image(i) & " and j= " & 319 Integer'Image(j)); 320 end if; 321 if not Incorrect_Inverse_Base_10 and 322 not FXA5A00.Result_Within_Range 323 (Float(i)**Float(j), 324 10.0**(Float(j)*EF.Log(Float(i),10.0)), 325 TC_Relative_Error) 326 then 327 Incorrect_Inverse_Base_10 := True; 328 Report.Failed("Incorrect Log-** Inverse calc for Base 10 " & 329 "with i= " & Integer'Image(i) & " and j= " & 330 Integer'Image(j)); 331 end if; 332 if not Incorrect_Inverse_Base_16 and 333 not FXA5A00.Result_Within_Range 334 (Float(i)**Float(j), 335 16.0**(Float(j)*EF.Log(Float(i),16.0)), 336 TC_Relative_Error) 337 then 338 Incorrect_Inverse_Base_16 := True; 339 Report.Failed("Incorrect Log-** Inverse calc for Base 16 " & 340 "with i= " & Integer'Image(i) & " and j= " & 341 Integer'Image(j)); 342 end if; 343 end loop; 344 end loop; 345 end; 346 347 -- Reset Flags. 348 Incorrect_Inverse_Base_e := False; 349 Incorrect_Inverse_Base_2 := False; 350 Incorrect_Inverse_Base_8 := False; 351 Incorrect_Inverse_Base_10 := False; 352 Incorrect_Inverse_Base_16 := False; 353 354 355 -- Testing of Exp Function, both instantiated and pre-instantiated 356 -- version. 357 358 -- Check that the result of the Exp Function, when provided an X 359 -- parameter value of 0.0, is 1.0. 360 361 if GEF.Exp(X => 0.0) /= 1.0 or 362 EF.Exp(0.0) /= 1.0 363 then 364 Report.Failed("Incorrect result returned by Function Exp when " & 365 "given a parameter value of 0.0"); 366 end if; 367 368 369 -- Check that the Exp Function provides correct results when provided 370 -- a variety of input parameter values. 371 372 if not Result_Within_Range(GEF.Exp(0.001), 1.01, 0.01) or 373 not Result_Within_Range( EF.Exp(0.1), 1.11, 0.01) or 374 not Result_Within_Range(GEF.Exp(1.2697), 3.56, 0.01) or 375 not Result_Within_Range( EF.Exp(3.2525), 25.9, 0.1) or 376 not Result_Within_Range(GEF.Exp(-0.2198), 0.803, 0.001) or 377 not Result_Within_Range( EF.Exp(-1.6621), 0.190, 0.001) or 378 not Result_Within_Range(GEF.Exp(-2.3888), 0.092, 0.001) or 379 not Result_Within_Range( EF.Exp(-5.4415), 0.004, 0.001) 380 then 381 Report.Failed("Incorrect result from Function Exp when provided " & 382 "a variety of input parameter values"); 383 end if; 384 385 -- Use the following loops to check for internal consistency between 386 -- inverse functions. 387 388 Arg := 0.01; 389 while Arg < 10.0 loop 390 if not Incorrect_Inverse_Base_e and 391 FXA5A00.Result_Within_Range(EF.Exp(Arg), 392 e**(Arg*EF.Log(Arg)), 393 0.001) 394 then 395 Incorrect_Inverse_Base_e := True; 396 Report.Failed("Incorrect Exp-** Inverse calc for Base e"); 397 end if; 398 if not Incorrect_Inverse_Base_2 and 399 FXA5A00.Result_Within_Range(EF.Exp(Arg), 400 2.0**(Arg*EF.Log(Arg,2.0)), 401 0.001) 402 then 403 Incorrect_Inverse_Base_2 := True; 404 Report.Failed("Incorrect Exp-** Inverse calc for Base 2"); 405 end if; 406 if not Incorrect_Inverse_Base_8 and 407 FXA5A00.Result_Within_Range(EF.Exp(Arg), 408 8.0**(Arg*EF.Log(Arg,8.0)), 409 0.001) 410 then 411 Incorrect_Inverse_Base_8 := True; 412 Report.Failed("Incorrect Exp-** Inverse calc for Base 8"); 413 end if; 414 if not Incorrect_Inverse_Base_10 and 415 FXA5A00.Result_Within_Range(EF.Exp(Arg), 416 10.0**(Arg*EF.Log(Arg,10.0)), 417 0.001) 418 then 419 Incorrect_Inverse_Base_10 := True; 420 Report.Failed("Incorrect Exp-** Inverse calc for Base 10"); 421 end if; 422 if not Incorrect_Inverse_Base_16 and 423 FXA5A00.Result_Within_Range(EF.Exp(Arg), 424 16.0**(Arg*EF.Log(Arg,16.0)), 425 0.001) 426 then 427 Incorrect_Inverse_Base_16 := True; 428 Report.Failed("Incorrect Exp-** Inverse calc for Base 16"); 429 end if; 430 Arg := Arg + 0.01; 431 end loop; 432 433 434 -- Testing of Sqrt Function, both instantiated and pre-instantiated 435 -- version. 436 437 -- Check that Argument_Error is raised by the Sqrt Function when 438 -- the value of the input parameter X is negative. 439 440 begin 441 Float_Result := EF.Sqrt(X => -FXA5A00.Small); 442 Report.Failed("Argument_Error not raised by Function Sqrt " & 443 "when provided a small negative input parameter " & 444 "value"); 445 Dont_Optimize_Float(Float_Result, 7); 446 exception 447 when Argument_Error => null; -- OK, expected exception. 448 when others => 449 Report.Failed("Unexpected exception raised by Function Sqrt " & 450 "when provided a small negative input parameter " & 451 "value"); 452 end; 453 454 begin 455 New_Float_Result := GEF.Sqrt(X => -64.0); 456 Report.Failed("Argument_Error not raised by Function Sqrt " & 457 "when provided a large negative input parameter " & 458 "value"); 459 Dont_Optimize_New_Float(New_Float_Result, 8); 460 exception 461 when Argument_Error => null; -- OK, expected exception. 462 when others => 463 Report.Failed("Unexpected exception raised by Function Sqrt " & 464 "when provided a large negative input parameter " & 465 "value"); 466 end; 467 468 469 -- Check that the Sqrt Function, when given an X parameter value of 0.0, 470 -- returns a result of 0.0. 471 472 if GEF.Sqrt(X => 0.0) /= 0.0 or 473 EF.Sqrt(0.0) /= 0.0 474 then 475 Report.Failed("Incorrect result from Function Sqrt when provided " & 476 "an input parameter value of 0.0"); 477 end if; 478 479 480 -- Check that the Sqrt Function, when given an X parameter input value 481 -- of 1.0, returns a result of 1.0. 482 483 if GEF.Sqrt(X => 1.0) /= 1.0 or 484 EF.Sqrt(1.0) /= 1.0 485 then 486 Report.Failed("Incorrect result from Function Sqrt when provided " & 487 "an input parameter value of 1.0"); 488 end if; 489 490 491 -- Check that the Sqrt Function provides correct results when provided 492 -- a variety of input parameter values. 493 494 if not FXA5A00.Result_Within_Range(GEF.Sqrt(0.0327), 0.181, 0.001) or 495 not FXA5A00.Result_Within_Range( EF.Sqrt(0.1808), 0.425, 0.001) or 496 not FXA5A00.Result_Within_Range(GEF.Sqrt(1.0556), 1.03, 0.01) or 497 not FXA5A00.Result_Within_Range( EF.Sqrt(32.8208), 5.73, 0.01) or 498 not FXA5A00.Result_Within_Range( EF.Sqrt(27851.0), 166.9, 0.1) or 499 not FXA5A00.Result_Within_Range( EF.Sqrt(61203.4), 247.4, 0.1) or 500 not FXA5A00.Result_Within_Range( EF.Sqrt(655891.0), 809.9, 0.1) 501 then 502 Report.Failed("Incorrect result from Function Sqrt when provided " & 503 "a variety of input parameter values"); 504 end if; 505 506 -- Check internal consistency between functions. 507 508 Arg := 0.01; 509 while Arg < 10.0 loop 510 if not Flag_1 and 511 not FXA5A00.Result_Within_Range(Arg, 512 EF.Sqrt(Arg)*EF.Sqrt(Arg), 513 0.01) 514 then 515 Report.Failed("Inconsistency found in Case 1"); 516 Flag_1 := True; 517 end if; 518 if not Flag_2 and 519 not FXA5A00.Result_Within_Range(Arg, EF.Sqrt(Arg)**2.0, 0.01) 520 then 521 Report.Failed("Inconsistency found in Case 2"); 522 Flag_2 := True; 523 end if; 524 if not Flag_3 and 525 not FXA5A00.Result_Within_Range(EF.Log(Arg), 526 EF.Log(Sqrt(Arg)**2.0), 0.01) 527 then 528 Report.Failed("Inconsistency found in Case 3"); 529 Flag_3 := True; 530 end if; 531 if not Flag_4 and 532 not FXA5A00.Result_Within_Range(EF.Log(Arg), 533 2.00*EF.Log(EF.Sqrt(Arg)), 534 0.01) 535 then 536 Report.Failed("Inconsistency found in Case 4"); 537 Flag_4 := True; 538 end if; 539 Arg := Arg + 1.0; 540 end loop; 541 542 543 exception 544 when The_Error : others => 545 Report.Failed ("The following exception was raised in the " & 546 "Test_Block: " & Exception_Name(The_Error)); 547 end Test_Block; 548 549 Report.Result; 550 551end CXA5A10; 552