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 |