| OLD | NEW |
| 1 /************************************************************************* | 1 /************************************************************************* |
| 2 * | 2 * |
| 3 * $Id$ | 3 * $Id$ |
| 4 * | 4 * |
| 5 * Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net> | 5 * Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net> |
| 6 * | 6 * |
| 7 * Permission to use, copy, modify, and distribute this software for any | 7 * Permission to use, copy, modify, and distribute this software for any |
| 8 * purpose with or without fee is hereby granted, provided that the above | 8 * purpose with or without fee is hereby granted, provided that the above |
| 9 * copyright notice and this permission notice appear in all copies. | 9 * copyright notice and this permission notice appear in all copies. |
| 10 * | 10 * |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 | 254 |
| 255 @return Floating-point representation of positive infinity. | 255 @return Floating-point representation of positive infinity. |
| 256 */ | 256 */ |
| 257 TRIO_PUBLIC double | 257 TRIO_PUBLIC double |
| 258 trio_pinf(TRIO_NOARGS) | 258 trio_pinf(TRIO_NOARGS) |
| 259 { | 259 { |
| 260 /* Cache the result */ | 260 /* Cache the result */ |
| 261 static double result = 0.0; | 261 static double result = 0.0; |
| 262 | 262 |
| 263 if (result == 0.0) { | 263 if (result == 0.0) { |
| 264 | 264 |
| 265 #if defined(INFINITY) && defined(__STDC_IEC_559__) | 265 #if defined(INFINITY) && defined(__STDC_IEC_559__) |
| 266 result = (double)INFINITY; | 266 result = (double)INFINITY; |
| 267 | 267 |
| 268 #elif defined(USE_IEEE_754) | 268 #elif defined(USE_IEEE_754) |
| 269 result = trio_make_double(ieee_754_infinity_array); | 269 result = trio_make_double(ieee_754_infinity_array); |
| 270 | 270 |
| 271 #else | 271 #else |
| 272 /* | 272 /* |
| 273 * If HUGE_VAL is different from DBL_MAX, then HUGE_VAL is used | 273 * If HUGE_VAL is different from DBL_MAX, then HUGE_VAL is used |
| 274 * as infinity. Otherwise we have to resort to an overflow | 274 * as infinity. Otherwise we have to resort to an overflow |
| 275 * operation to generate infinity. | 275 * operation to generate infinity. |
| 276 */ | 276 */ |
| 277 # if defined(TRIO_PLATFORM_UNIX) | 277 # if defined(TRIO_PLATFORM_UNIX) |
| 278 void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN); | 278 void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN); |
| 279 # endif | 279 # endif |
| 280 | 280 |
| 281 result = HUGE_VAL; | 281 result = HUGE_VAL; |
| 282 if (HUGE_VAL == DBL_MAX) { | 282 if (HUGE_VAL == DBL_MAX) { |
| 283 /* Force overflow */ | 283 /* Force overflow */ |
| 284 result += HUGE_VAL; | 284 result += HUGE_VAL; |
| 285 } | 285 } |
| 286 | 286 |
| 287 # if defined(TRIO_PLATFORM_UNIX) | 287 # if defined(TRIO_PLATFORM_UNIX) |
| 288 signal(SIGFPE, signal_handler); | 288 signal(SIGFPE, signal_handler); |
| 289 # endif | 289 # endif |
| 290 | 290 |
| 291 #endif | 291 #endif |
| 292 } | 292 } |
| 293 return result; | 293 return result; |
| 294 } | 294 } |
| 295 | 295 |
| 296 /** | 296 /** |
| (...skipping 22 matching lines...) Expand all Loading... |
| 319 | 319 |
| 320 @return Floating-point representation of NaN. | 320 @return Floating-point representation of NaN. |
| 321 */ | 321 */ |
| 322 TRIO_PUBLIC double | 322 TRIO_PUBLIC double |
| 323 trio_nan(TRIO_NOARGS) | 323 trio_nan(TRIO_NOARGS) |
| 324 { | 324 { |
| 325 /* Cache the result */ | 325 /* Cache the result */ |
| 326 static double result = 0.0; | 326 static double result = 0.0; |
| 327 | 327 |
| 328 if (result == 0.0) { | 328 if (result == 0.0) { |
| 329 | 329 |
| 330 #if defined(TRIO_COMPILER_SUPPORTS_C99) | 330 #if defined(TRIO_COMPILER_SUPPORTS_C99) |
| 331 result = nan(""); | 331 result = nan(""); |
| 332 | 332 |
| 333 #elif defined(NAN) && defined(__STDC_IEC_559__) | 333 #elif defined(NAN) && defined(__STDC_IEC_559__) |
| 334 result = (double)NAN; | 334 result = (double)NAN; |
| 335 | 335 |
| 336 #elif defined(USE_IEEE_754) | 336 #elif defined(USE_IEEE_754) |
| 337 result = trio_make_double(ieee_754_qnan_array); | 337 result = trio_make_double(ieee_754_qnan_array); |
| 338 | 338 |
| 339 #else | 339 #else |
| 340 /* | 340 /* |
| 341 * There are several ways to generate NaN. The one used here is | 341 * There are several ways to generate NaN. The one used here is |
| 342 * to divide infinity by infinity. I would have preferred to add | 342 * to divide infinity by infinity. I would have preferred to add |
| 343 * negative infinity to positive infinity, but that yields wrong | 343 * negative infinity to positive infinity, but that yields wrong |
| 344 * result (infinity) on FreeBSD. | 344 * result (infinity) on FreeBSD. |
| 345 * | 345 * |
| 346 * This may fail if the hardware does not support NaN, or if | 346 * This may fail if the hardware does not support NaN, or if |
| 347 * the Invalid Operation floating-point exception is unmasked. | 347 * the Invalid Operation floating-point exception is unmasked. |
| 348 */ | 348 */ |
| 349 # if defined(TRIO_PLATFORM_UNIX) | 349 # if defined(TRIO_PLATFORM_UNIX) |
| 350 void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN); | 350 void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN); |
| 351 # endif | 351 # endif |
| 352 | 352 |
| 353 result = trio_pinf() / trio_pinf(); | 353 result = trio_pinf() / trio_pinf(); |
| 354 | 354 |
| 355 # if defined(TRIO_PLATFORM_UNIX) | 355 # if defined(TRIO_PLATFORM_UNIX) |
| 356 signal(SIGFPE, signal_handler); | 356 signal(SIGFPE, signal_handler); |
| 357 # endif | 357 # endif |
| 358 | 358 |
| 359 #endif | 359 #endif |
| 360 } | 360 } |
| 361 return result; | 361 return result; |
| 362 } | 362 } |
| 363 | 363 |
| 364 /** | 364 /** |
| 365 Check for NaN. | 365 Check for NaN. |
| 366 | 366 |
| 367 @param number An arbitrary floating-point number. | 367 @param number An arbitrary floating-point number. |
| 368 @return Boolean value indicating whether or not the number is a NaN. | 368 @return Boolean value indicating whether or not the number is a NaN. |
| 369 */ | 369 */ |
| 370 TRIO_PUBLIC int | 370 TRIO_PUBLIC int |
| 371 trio_isnan | 371 trio_isnan |
| 372 TRIO_ARGS1((number), | 372 TRIO_ARGS1((number), |
| 373 double number) | 373 double number) |
| 374 { | 374 { |
| 375 #if (defined(TRIO_COMPILER_SUPPORTS_C99) && defined(isnan)) \ | 375 #if (defined(TRIO_COMPILER_SUPPORTS_C99) && defined(isnan)) \ |
| 376 || defined(TRIO_COMPILER_SUPPORTS_UNIX95) | 376 || defined(TRIO_COMPILER_SUPPORTS_UNIX95) |
| 377 /* | 377 /* |
| 378 * C99 defines isnan() as a macro. UNIX95 defines isnan() as a | 378 * C99 defines isnan() as a macro. UNIX95 defines isnan() as a |
| 379 * function. This function was already present in XPG4, but this | 379 * function. This function was already present in XPG4, but this |
| 380 * is a bit tricky to detect with compiler defines, so we choose | 380 * is a bit tricky to detect with compiler defines, so we choose |
| 381 * the conservative approach and only use it for UNIX95. | 381 * the conservative approach and only use it for UNIX95. |
| 382 */ | 382 */ |
| 383 return isnan(number); | 383 return isnan(number); |
| 384 | 384 |
| 385 #elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB) | 385 #elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB) |
| 386 /* | 386 /* |
| 387 * Microsoft Visual C++ and Borland C++ Builder have an _isnan() | 387 * Microsoft Visual C++ and Borland C++ Builder have an _isnan() |
| 388 * function. | 388 * function. |
| 389 */ | 389 */ |
| 390 return _isnan(number) ? TRIO_TRUE : TRIO_FALSE; | 390 return _isnan(number) ? TRIO_TRUE : TRIO_FALSE; |
| 391 | 391 |
| 392 #elif defined(USE_IEEE_754) | 392 #elif defined(USE_IEEE_754) |
| 393 /* | 393 /* |
| 394 * Examine IEEE 754 bit-pattern. A NaN must have a special exponent | 394 * Examine IEEE 754 bit-pattern. A NaN must have a special exponent |
| 395 * pattern, and a non-empty mantissa. | 395 * pattern, and a non-empty mantissa. |
| 396 */ | 396 */ |
| 397 int has_mantissa; | 397 int has_mantissa; |
| 398 int is_special_quantity; | 398 int is_special_quantity; |
| 399 | 399 |
| 400 is_special_quantity = trio_is_special_quantity(number, &has_mantissa); | 400 is_special_quantity = trio_is_special_quantity(number, &has_mantissa); |
| 401 | 401 |
| 402 return (is_special_quantity && has_mantissa); | 402 return (is_special_quantity && has_mantissa); |
| 403 | 403 |
| 404 #else | 404 #else |
| 405 /* | 405 /* |
| 406 * Fallback solution | 406 * Fallback solution |
| 407 */ | 407 */ |
| 408 int status; | 408 int status; |
| 409 double integral, fraction; | 409 double integral, fraction; |
| 410 | 410 |
| 411 # if defined(TRIO_PLATFORM_UNIX) | 411 # if defined(TRIO_PLATFORM_UNIX) |
| 412 void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN); | 412 void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN); |
| 413 # endif | 413 # endif |
| 414 | 414 |
| 415 status = (/* | 415 status = (/* |
| 416 * NaN is the only number which does not compare to itself | 416 * NaN is the only number which does not compare to itself |
| 417 */ | 417 */ |
| 418 ((TRIO_VOLATILE double)number != (TRIO_VOLATILE double)number) || | 418 ((TRIO_VOLATILE double)number != (TRIO_VOLATILE double)number) || |
| 419 /* | 419 /* |
| 420 * Fallback solution if NaN compares to NaN | 420 * Fallback solution if NaN compares to NaN |
| 421 */ | 421 */ |
| 422 ((number != 0.0) && | 422 ((number != 0.0) && |
| 423 (fraction = modf(number, &integral), | 423 (fraction = modf(number, &integral), |
| 424 integral == fraction))); | 424 integral == fraction))); |
| 425 | 425 |
| 426 # if defined(TRIO_PLATFORM_UNIX) | 426 # if defined(TRIO_PLATFORM_UNIX) |
| 427 signal(SIGFPE, signal_handler); | 427 signal(SIGFPE, signal_handler); |
| 428 # endif | 428 # endif |
| 429 | 429 |
| 430 return status; | 430 return status; |
| 431 | 431 |
| 432 #endif | 432 #endif |
| 433 } | 433 } |
| 434 | 434 |
| 435 /** | 435 /** |
| 436 Check for infinity. | 436 Check for infinity. |
| 437 | 437 |
| 438 @param number An arbitrary floating-point number. | 438 @param number An arbitrary floating-point number. |
| 439 @return 1 if positive infinity, -1 if negative infinity, 0 otherwise. | 439 @return 1 if positive infinity, -1 if negative infinity, 0 otherwise. |
| 440 */ | 440 */ |
| 441 TRIO_PUBLIC int | 441 TRIO_PUBLIC int |
| (...skipping 10 matching lines...) Expand all Loading... |
| 452 ? 1 | 452 ? 1 |
| 453 : ((fp_class(number) == FP_NEG_INF) ? -1 : 0)); | 453 : ((fp_class(number) == FP_NEG_INF) ? -1 : 0)); |
| 454 | 454 |
| 455 #elif defined(isinf) | 455 #elif defined(isinf) |
| 456 /* | 456 /* |
| 457 * C99 defines isinf() as a macro. | 457 * C99 defines isinf() as a macro. |
| 458 */ | 458 */ |
| 459 return isinf(number) | 459 return isinf(number) |
| 460 ? ((number > 0.0) ? 1 : -1) | 460 ? ((number > 0.0) ? 1 : -1) |
| 461 : 0; | 461 : 0; |
| 462 | 462 |
| 463 #elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB) | 463 #elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB) |
| 464 /* | 464 /* |
| 465 * Microsoft Visual C++ and Borland C++ Builder have an _fpclass() | 465 * Microsoft Visual C++ and Borland C++ Builder have an _fpclass() |
| 466 * function that can be used to detect infinity. | 466 * function that can be used to detect infinity. |
| 467 */ | 467 */ |
| 468 return ((_fpclass(number) == _FPCLASS_PINF) | 468 return ((_fpclass(number) == _FPCLASS_PINF) |
| 469 ? 1 | 469 ? 1 |
| 470 : ((_fpclass(number) == _FPCLASS_NINF) ? -1 : 0)); | 470 : ((_fpclass(number) == _FPCLASS_NINF) ? -1 : 0)); |
| 471 | 471 |
| 472 #elif defined(USE_IEEE_754) | 472 #elif defined(USE_IEEE_754) |
| 473 /* | 473 /* |
| 474 * Examine IEEE 754 bit-pattern. Infinity must have a special exponent | 474 * Examine IEEE 754 bit-pattern. Infinity must have a special exponent |
| 475 * pattern, and an empty mantissa. | 475 * pattern, and an empty mantissa. |
| 476 */ | 476 */ |
| 477 int has_mantissa; | 477 int has_mantissa; |
| 478 int is_special_quantity; | 478 int is_special_quantity; |
| 479 | 479 |
| 480 is_special_quantity = trio_is_special_quantity(number, &has_mantissa); | 480 is_special_quantity = trio_is_special_quantity(number, &has_mantissa); |
| 481 | 481 |
| 482 return (is_special_quantity && !has_mantissa) | 482 return (is_special_quantity && !has_mantissa) |
| 483 ? ((number < 0.0) ? -1 : 1) | 483 ? ((number < 0.0) ? -1 : 1) |
| 484 : 0; | 484 : 0; |
| 485 | 485 |
| 486 #else | 486 #else |
| 487 /* | 487 /* |
| 488 * Fallback solution. | 488 * Fallback solution. |
| 489 */ | 489 */ |
| 490 int status; | 490 int status; |
| 491 | 491 |
| 492 # if defined(TRIO_PLATFORM_UNIX) | 492 # if defined(TRIO_PLATFORM_UNIX) |
| 493 void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN); | 493 void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN); |
| 494 # endif | 494 # endif |
| 495 | 495 |
| 496 double infinity = trio_pinf(); | 496 double infinity = trio_pinf(); |
| 497 | 497 |
| 498 status = ((number == infinity) | 498 status = ((number == infinity) |
| 499 ? 1 | 499 ? 1 |
| 500 : ((number == -infinity) ? -1 : 0)); | 500 : ((number == -infinity) ? -1 : 0)); |
| 501 | 501 |
| 502 # if defined(TRIO_PLATFORM_UNIX) | 502 # if defined(TRIO_PLATFORM_UNIX) |
| 503 signal(SIGFPE, signal_handler); | 503 signal(SIGFPE, signal_handler); |
| 504 # endif | 504 # endif |
| 505 | 505 |
| 506 return status; | 506 return status; |
| 507 | 507 |
| 508 #endif | 508 #endif |
| 509 } | 509 } |
| 510 | 510 |
| 511 #if 0 | 511 #if 0 |
| 512 /* Temporary fix - this routine is not used anywhere */ | 512 /* Temporary fix - this routine is not used anywhere */ |
| 513 /** | 513 /** |
| 514 Check for finity. | 514 Check for finity. |
| 515 | 515 |
| 516 @param number An arbitrary floating-point number. | 516 @param number An arbitrary floating-point number. |
| 517 @return Boolean value indicating whether or not the number is a finite. | 517 @return Boolean value indicating whether or not the number is a finite. |
| 518 */ | 518 */ |
| 519 TRIO_PUBLIC int | 519 TRIO_PUBLIC int |
| 520 trio_isfinite | 520 trio_isfinite |
| 521 TRIO_ARGS1((number), | 521 TRIO_ARGS1((number), |
| 522 double number) | 522 double number) |
| 523 { | 523 { |
| 524 #if defined(TRIO_COMPILER_SUPPORTS_C99) && defined(isfinite) | 524 #if defined(TRIO_COMPILER_SUPPORTS_C99) && defined(isfinite) |
| 525 /* | 525 /* |
| 526 * C99 defines isfinite() as a macro. | 526 * C99 defines isfinite() as a macro. |
| 527 */ | 527 */ |
| 528 return isfinite(number); | 528 return isfinite(number); |
| 529 | 529 |
| 530 #elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB) | 530 #elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB) |
| 531 /* | 531 /* |
| 532 * Microsoft Visual C++ and Borland C++ Builder use _finite(). | 532 * Microsoft Visual C++ and Borland C++ Builder use _finite(). |
| 533 */ | 533 */ |
| 534 return _finite(number); | 534 return _finite(number); |
| 535 | 535 |
| 536 #elif defined(USE_IEEE_754) | 536 #elif defined(USE_IEEE_754) |
| 537 /* | 537 /* |
| 538 * Examine IEEE 754 bit-pattern. For finity we do not care about the | 538 * Examine IEEE 754 bit-pattern. For finity we do not care about the |
| 539 * mantissa. | 539 * mantissa. |
| 540 */ | 540 */ |
| 541 int dummy; | 541 int dummy; |
| 542 | 542 |
| 543 return (! trio_is_special_quantity(number, &dummy)); | 543 return (! trio_is_special_quantity(number, &dummy)); |
| 544 | 544 |
| 545 #else | 545 #else |
| 546 /* | 546 /* |
| 547 * Fallback solution. | 547 * Fallback solution. |
| 548 */ | 548 */ |
| 549 return ((trio_isinf(number) == 0) && (trio_isnan(number) == 0)); | 549 return ((trio_isinf(number) == 0) && (trio_isnan(number) == 0)); |
| 550 | 550 |
| 551 #endif | 551 #endif |
| 552 } | 552 } |
| 553 | 553 |
| 554 #endif | 554 #endif |
| 555 | 555 |
| 556 /* | 556 /* |
| 557 * The sign of NaN is always false | 557 * The sign of NaN is always false |
| 558 */ | 558 */ |
| 559 TRIO_PUBLIC int | 559 TRIO_PUBLIC int |
| 560 trio_fpclassify_and_signbit | 560 trio_fpclassify_and_signbit |
| (...skipping 28 matching lines...) Expand all Loading... |
| 589 # define TRIO_QUIET_NAN FP_QNAN | 589 # define TRIO_QUIET_NAN FP_QNAN |
| 590 # define TRIO_SIGNALLING_NAN FP_SNAN | 590 # define TRIO_SIGNALLING_NAN FP_SNAN |
| 591 # define TRIO_POSITIVE_INFINITY FP_POS_INF | 591 # define TRIO_POSITIVE_INFINITY FP_POS_INF |
| 592 # define TRIO_NEGATIVE_INFINITY FP_NEG_INF | 592 # define TRIO_NEGATIVE_INFINITY FP_NEG_INF |
| 593 # define TRIO_POSITIVE_SUBNORMAL FP_POS_DENORM | 593 # define TRIO_POSITIVE_SUBNORMAL FP_POS_DENORM |
| 594 # define TRIO_NEGATIVE_SUBNORMAL FP_NEG_DENORM | 594 # define TRIO_NEGATIVE_SUBNORMAL FP_NEG_DENORM |
| 595 # define TRIO_POSITIVE_ZERO FP_POS_ZERO | 595 # define TRIO_POSITIVE_ZERO FP_POS_ZERO |
| 596 # define TRIO_NEGATIVE_ZERO FP_NEG_ZERO | 596 # define TRIO_NEGATIVE_ZERO FP_NEG_ZERO |
| 597 # define TRIO_POSITIVE_NORMAL FP_POS_NORM | 597 # define TRIO_POSITIVE_NORMAL FP_POS_NORM |
| 598 # define TRIO_NEGATIVE_NORMAL FP_NEG_NORM | 598 # define TRIO_NEGATIVE_NORMAL FP_NEG_NORM |
| 599 | 599 |
| 600 # elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB) | 600 # elif defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB) |
| 601 /* | 601 /* |
| 602 * Microsoft Visual C++ and Borland C++ Builder have an _fpclass() | 602 * Microsoft Visual C++ and Borland C++ Builder have an _fpclass() |
| 603 * function. | 603 * function. |
| 604 */ | 604 */ |
| 605 # define TRIO_FPCLASSIFY(n) _fpclass(n) | 605 # define TRIO_FPCLASSIFY(n) _fpclass(n) |
| 606 # define TRIO_QUIET_NAN _FPCLASS_QNAN | 606 # define TRIO_QUIET_NAN _FPCLASS_QNAN |
| 607 # define TRIO_SIGNALLING_NAN _FPCLASS_SNAN | 607 # define TRIO_SIGNALLING_NAN _FPCLASS_SNAN |
| 608 # define TRIO_POSITIVE_INFINITY _FPCLASS_PINF | 608 # define TRIO_POSITIVE_INFINITY _FPCLASS_PINF |
| 609 # define TRIO_NEGATIVE_INFINITY _FPCLASS_NINF | 609 # define TRIO_NEGATIVE_INFINITY _FPCLASS_NINF |
| 610 # define TRIO_POSITIVE_SUBNORMAL _FPCLASS_PD | 610 # define TRIO_POSITIVE_SUBNORMAL _FPCLASS_PD |
| 611 # define TRIO_NEGATIVE_SUBNORMAL _FPCLASS_ND | 611 # define TRIO_NEGATIVE_SUBNORMAL _FPCLASS_ND |
| 612 # define TRIO_POSITIVE_ZERO _FPCLASS_PZ | 612 # define TRIO_POSITIVE_ZERO _FPCLASS_PZ |
| 613 # define TRIO_NEGATIVE_ZERO _FPCLASS_NZ | 613 # define TRIO_NEGATIVE_ZERO _FPCLASS_NZ |
| 614 # define TRIO_POSITIVE_NORMAL _FPCLASS_PN | 614 # define TRIO_POSITIVE_NORMAL _FPCLASS_PN |
| 615 # define TRIO_NEGATIVE_NORMAL _FPCLASS_NN | 615 # define TRIO_NEGATIVE_NORMAL _FPCLASS_NN |
| 616 | 616 |
| 617 # elif defined(FP_PLUS_NORM) | 617 # elif defined(FP_PLUS_NORM) |
| 618 /* | 618 /* |
| 619 * HP-UX 9.x and 10.x have an fpclassify() function, that is different | 619 * HP-UX 9.x and 10.x have an fpclassify() function, that is different |
| 620 * from the C99 fpclassify() macro supported on HP-UX 11.x. | 620 * from the C99 fpclassify() macro supported on HP-UX 11.x. |
| 621 * | 621 * |
| 622 * AIX has class() for C, and _class() for C++, which returns the | 622 * AIX has class() for C, and _class() for C++, which returns the |
| 623 * same values as the HP-UX fpclassify() function. | 623 * same values as the HP-UX fpclassify() function. |
| 624 */ | 624 */ |
| 625 # if defined(TRIO_PLATFORM_AIX) | 625 # if defined(TRIO_PLATFORM_AIX) |
| 626 # if defined(__cplusplus) | 626 # if defined(__cplusplus) |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 671 *is_negative = TRIO_FALSE; | 671 *is_negative = TRIO_FALSE; |
| 672 return TRIO_FP_NORMAL; | 672 return TRIO_FP_NORMAL; |
| 673 case TRIO_NEGATIVE_NORMAL: | 673 case TRIO_NEGATIVE_NORMAL: |
| 674 *is_negative = TRIO_TRUE; | 674 *is_negative = TRIO_TRUE; |
| 675 return TRIO_FP_NORMAL; | 675 return TRIO_FP_NORMAL; |
| 676 default: | 676 default: |
| 677 /* Just in case... */ | 677 /* Just in case... */ |
| 678 *is_negative = (number < 0.0); | 678 *is_negative = (number < 0.0); |
| 679 return TRIO_FP_NORMAL; | 679 return TRIO_FP_NORMAL; |
| 680 } | 680 } |
| 681 | 681 |
| 682 # else | 682 # else |
| 683 /* | 683 /* |
| 684 * Fallback solution. | 684 * Fallback solution. |
| 685 */ | 685 */ |
| 686 int rc; | 686 int rc; |
| 687 | 687 |
| 688 if (number == 0.0) { | 688 if (number == 0.0) { |
| 689 /* | 689 /* |
| 690 * In IEEE 754 the sign of zero is ignored in comparisons, so we | 690 * In IEEE 754 the sign of zero is ignored in comparisons, so we |
| 691 * have to handle this as a special case by examining the sign bit | 691 * have to handle this as a special case by examining the sign bit |
| 692 * directly. | 692 * directly. |
| 693 */ | 693 */ |
| 694 # if defined(USE_IEEE_754) | 694 # if defined(USE_IEEE_754) |
| 695 *is_negative = trio_is_negative(number); | 695 *is_negative = trio_is_negative(number); |
| 696 # else | 696 # else |
| 697 *is_negative = TRIO_FALSE; /* FIXME */ | 697 *is_negative = TRIO_FALSE; /* FIXME */ |
| (...skipping 11 matching lines...) Expand all Loading... |
| 709 if ((number > 0.0) && (number < DBL_MIN)) { | 709 if ((number > 0.0) && (number < DBL_MIN)) { |
| 710 *is_negative = TRIO_FALSE; | 710 *is_negative = TRIO_FALSE; |
| 711 return TRIO_FP_SUBNORMAL; | 711 return TRIO_FP_SUBNORMAL; |
| 712 } | 712 } |
| 713 if ((number < 0.0) && (number > -DBL_MIN)) { | 713 if ((number < 0.0) && (number > -DBL_MIN)) { |
| 714 *is_negative = TRIO_TRUE; | 714 *is_negative = TRIO_TRUE; |
| 715 return TRIO_FP_SUBNORMAL; | 715 return TRIO_FP_SUBNORMAL; |
| 716 } | 716 } |
| 717 *is_negative = (number < 0.0); | 717 *is_negative = (number < 0.0); |
| 718 return TRIO_FP_NORMAL; | 718 return TRIO_FP_NORMAL; |
| 719 | 719 |
| 720 # endif | 720 # endif |
| 721 #endif | 721 #endif |
| 722 } | 722 } |
| 723 | 723 |
| 724 /** | 724 /** |
| 725 Examine the sign of a number. | 725 Examine the sign of a number. |
| 726 | 726 |
| 727 @param number An arbitrary floating-point number. | 727 @param number An arbitrary floating-point number. |
| 728 @return Boolean value indicating whether or not the number has the | 728 @return Boolean value indicating whether or not the number has the |
| 729 sign bit set (i.e. is negative). | 729 sign bit set (i.e. is negative). |
| 730 */ | 730 */ |
| 731 TRIO_PUBLIC int | 731 TRIO_PUBLIC int |
| 732 trio_signbit | 732 trio_signbit |
| 733 TRIO_ARGS1((number), | 733 TRIO_ARGS1((number), |
| 734 double number) | 734 double number) |
| 735 { | 735 { |
| 736 int is_negative; | 736 int is_negative; |
| 737 | 737 |
| 738 (void)trio_fpclassify_and_signbit(number, &is_negative); | 738 (void)trio_fpclassify_and_signbit(number, &is_negative); |
| 739 return is_negative; | 739 return is_negative; |
| 740 } | 740 } |
| 741 | 741 |
| 742 #if 0 | 742 #if 0 |
| 743 /* Temporary fix - this routine is not used in libxml */ | 743 /* Temporary fix - this routine is not used in libxml */ |
| 744 /** | 744 /** |
| 745 Examine the class of a number. | 745 Examine the class of a number. |
| 746 | 746 |
| 747 @param number An arbitrary floating-point number. | 747 @param number An arbitrary floating-point number. |
| 748 @return Enumerable value indicating the class of @p number | 748 @return Enumerable value indicating the class of @p number |
| 749 */ | 749 */ |
| 750 TRIO_PUBLIC int | 750 TRIO_PUBLIC int |
| 751 trio_fpclassify | 751 trio_fpclassify |
| 752 TRIO_ARGS1((number), | 752 TRIO_ARGS1((number), |
| 753 double number) | 753 double number) |
| 754 { | 754 { |
| 755 int dummy; | 755 int dummy; |
| 756 | 756 |
| 757 return trio_fpclassify_and_signbit(number, &dummy); | 757 return trio_fpclassify_and_signbit(number, &dummy); |
| 758 } | 758 } |
| 759 | 759 |
| 760 #endif | 760 #endif |
| 761 | 761 |
| 762 /** @} SpecialQuantities */ | 762 /** @} SpecialQuantities */ |
| 763 | 763 |
| 764 /************************************************************************* | 764 /************************************************************************* |
| 765 * For test purposes. | 765 * For test purposes. |
| 766 * | 766 * |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 821 | 821 |
| 822 print_class("Nan", my_nan); | 822 print_class("Nan", my_nan); |
| 823 print_class("PInf", my_pinf); | 823 print_class("PInf", my_pinf); |
| 824 print_class("NInf", my_ninf); | 824 print_class("NInf", my_ninf); |
| 825 print_class("PZero", 0.0); | 825 print_class("PZero", 0.0); |
| 826 print_class("NZero", -0.0); | 826 print_class("NZero", -0.0); |
| 827 print_class("PNorm", 1.0); | 827 print_class("PNorm", 1.0); |
| 828 print_class("NNorm", -1.0); | 828 print_class("NNorm", -1.0); |
| 829 print_class("PSub", 1.01e-307 - 1.00e-307); | 829 print_class("PSub", 1.01e-307 - 1.00e-307); |
| 830 print_class("NSub", 1.00e-307 - 1.01e-307); | 830 print_class("NSub", 1.00e-307 - 1.01e-307); |
| 831 | 831 |
| 832 printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n", | 832 printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n", |
| 833 my_nan, | 833 my_nan, |
| 834 ((unsigned char *)&my_nan)[0], | 834 ((unsigned char *)&my_nan)[0], |
| 835 ((unsigned char *)&my_nan)[1], | 835 ((unsigned char *)&my_nan)[1], |
| 836 ((unsigned char *)&my_nan)[2], | 836 ((unsigned char *)&my_nan)[2], |
| 837 ((unsigned char *)&my_nan)[3], | 837 ((unsigned char *)&my_nan)[3], |
| 838 ((unsigned char *)&my_nan)[4], | 838 ((unsigned char *)&my_nan)[4], |
| 839 ((unsigned char *)&my_nan)[5], | 839 ((unsigned char *)&my_nan)[5], |
| 840 ((unsigned char *)&my_nan)[6], | 840 ((unsigned char *)&my_nan)[6], |
| 841 ((unsigned char *)&my_nan)[7], | 841 ((unsigned char *)&my_nan)[7], |
| (...skipping 13 matching lines...) Expand all Loading... |
| 855 my_ninf, | 855 my_ninf, |
| 856 ((unsigned char *)&my_ninf)[0], | 856 ((unsigned char *)&my_ninf)[0], |
| 857 ((unsigned char *)&my_ninf)[1], | 857 ((unsigned char *)&my_ninf)[1], |
| 858 ((unsigned char *)&my_ninf)[2], | 858 ((unsigned char *)&my_ninf)[2], |
| 859 ((unsigned char *)&my_ninf)[3], | 859 ((unsigned char *)&my_ninf)[3], |
| 860 ((unsigned char *)&my_ninf)[4], | 860 ((unsigned char *)&my_ninf)[4], |
| 861 ((unsigned char *)&my_ninf)[5], | 861 ((unsigned char *)&my_ninf)[5], |
| 862 ((unsigned char *)&my_ninf)[6], | 862 ((unsigned char *)&my_ninf)[6], |
| 863 ((unsigned char *)&my_ninf)[7], | 863 ((unsigned char *)&my_ninf)[7], |
| 864 trio_isnan(my_ninf), trio_isinf(my_ninf)); | 864 trio_isnan(my_ninf), trio_isinf(my_ninf)); |
| 865 | 865 |
| 866 # if defined(TRIO_PLATFORM_UNIX) | 866 # if defined(TRIO_PLATFORM_UNIX) |
| 867 signal_handler = signal(SIGFPE, SIG_IGN); | 867 signal_handler = signal(SIGFPE, SIG_IGN); |
| 868 # endif | 868 # endif |
| 869 | 869 |
| 870 my_pinf = DBL_MAX + DBL_MAX; | 870 my_pinf = DBL_MAX + DBL_MAX; |
| 871 my_ninf = -my_pinf; | 871 my_ninf = -my_pinf; |
| 872 my_nan = my_pinf / my_pinf; | 872 my_nan = my_pinf / my_pinf; |
| 873 | 873 |
| 874 # if defined(TRIO_PLATFORM_UNIX) | 874 # if defined(TRIO_PLATFORM_UNIX) |
| 875 signal(SIGFPE, signal_handler); | 875 signal(SIGFPE, signal_handler); |
| 876 # endif | 876 # endif |
| 877 | 877 |
| 878 printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n", | 878 printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n", |
| 879 my_nan, | 879 my_nan, |
| 880 ((unsigned char *)&my_nan)[0], | 880 ((unsigned char *)&my_nan)[0], |
| 881 ((unsigned char *)&my_nan)[1], | 881 ((unsigned char *)&my_nan)[1], |
| 882 ((unsigned char *)&my_nan)[2], | 882 ((unsigned char *)&my_nan)[2], |
| 883 ((unsigned char *)&my_nan)[3], | 883 ((unsigned char *)&my_nan)[3], |
| 884 ((unsigned char *)&my_nan)[4], | 884 ((unsigned char *)&my_nan)[4], |
| 885 ((unsigned char *)&my_nan)[5], | 885 ((unsigned char *)&my_nan)[5], |
| 886 ((unsigned char *)&my_nan)[6], | 886 ((unsigned char *)&my_nan)[6], |
| 887 ((unsigned char *)&my_nan)[7], | 887 ((unsigned char *)&my_nan)[7], |
| (...skipping 13 matching lines...) Expand all Loading... |
| 901 my_ninf, | 901 my_ninf, |
| 902 ((unsigned char *)&my_ninf)[0], | 902 ((unsigned char *)&my_ninf)[0], |
| 903 ((unsigned char *)&my_ninf)[1], | 903 ((unsigned char *)&my_ninf)[1], |
| 904 ((unsigned char *)&my_ninf)[2], | 904 ((unsigned char *)&my_ninf)[2], |
| 905 ((unsigned char *)&my_ninf)[3], | 905 ((unsigned char *)&my_ninf)[3], |
| 906 ((unsigned char *)&my_ninf)[4], | 906 ((unsigned char *)&my_ninf)[4], |
| 907 ((unsigned char *)&my_ninf)[5], | 907 ((unsigned char *)&my_ninf)[5], |
| 908 ((unsigned char *)&my_ninf)[6], | 908 ((unsigned char *)&my_ninf)[6], |
| 909 ((unsigned char *)&my_ninf)[7], | 909 ((unsigned char *)&my_ninf)[7], |
| 910 trio_isnan(my_ninf), trio_isinf(my_ninf)); | 910 trio_isnan(my_ninf), trio_isinf(my_ninf)); |
| 911 | 911 |
| 912 return 0; | 912 return 0; |
| 913 } | 913 } |
| 914 #endif | 914 #endif |
| OLD | NEW |