[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: new module 'isnanl-nolibm'
From: |
Bruno Haible |
Subject: |
Re: new module 'isnanl-nolibm' |
Date: |
Sun, 25 Feb 2007 03:34:57 +0100 |
User-agent: |
KMail/1.5.4 |
Oops, this was code duplication, which is bad. I'm merging the two functions
into a single code.
2007-02-24 Bruno Haible <address@hidden>
* lib/isnan.c: Support the 'long double' case if USE_LONG_DOUBLE is
defined.
* lib/isnanl.c: Remove all code. Just include isnan.c.
* modules/isnanl-nolibm (Files): Add lib/isnan.c.
*** lib/isnan.c 24 Feb 2007 19:08:56 -0000 1.1
--- lib/isnan.c 25 Feb 2007 02:28:51 -0000
***************
*** 22,53 ****
#include <float.h>
#include <string.h>
! #define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7)
#define NWORDS \
! ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
! typedef union { double value; unsigned int word[NWORDS]; } memory_double;
int
! rpl_isnan (double x)
{
! #if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
/* Be careful to not do any floating-point operation on x, such as x == x,
because x may be a signaling NaN. */
! static memory_double nan = { 0.0 / 0.0 };
! static double plus_inf = 1.0 / 0.0;
! static double minus_inf = -1.0 / 0.0;
memory_double m;
/* A NaN can be recognized through its exponent. But exclude +Infinity and
-Infinity, which have the same exponent. */
m.value = x;
! if ((((m.word[DBL_EXPBIT0_WORD] >> DBL_EXPBIT0_BIT)
! ^ (nan.word[DBL_EXPBIT0_WORD] >> DBL_EXPBIT0_BIT))
! & DBL_EXP_MASK)
== 0)
! return (memcmp (&m.value, &plus_inf, sizeof (double)) != 0
! && memcmp (&m.value, &minus_inf, sizeof (double)) != 0);
else
return 0;
#else
--- 22,76 ----
#include <float.h>
#include <string.h>
! #ifdef USE_LONG_DOUBLE
! # define FUNC rpl_isnanl
! # define DOUBLE long double
! # define MAX_EXP LDBL_MAX_EXP
! # define MIN_EXP LDBL_MIN_EXP
! # if defined LDBL_EXPBIT0_WORD && defined LDBL_EXPBIT0_BIT
! # define KNOWN_EXPBIT0_LOCATION
! # define EXPBIT0_WORD LDBL_EXPBIT0_WORD
! # define EXPBIT0_BIT LDBL_EXPBIT0_BIT
! # endif
! # define L_(literal) literal##L
! #else
! # define FUNC rpl_isnan
! # define DOUBLE double
! # define MAX_EXP DBL_MAX_EXP
! # define MIN_EXP DBL_MIN_EXP
! # if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
! # define KNOWN_EXPBIT0_LOCATION
! # define EXPBIT0_WORD DBL_EXPBIT0_WORD
! # define EXPBIT0_BIT DBL_EXPBIT0_BIT
! # endif
! # define L_(literal) literal
! #endif
!
! #define EXP_MASK ((MAX_EXP - MIN_EXP) | 7)
#define NWORDS \
! ((sizeof (DOUBLE) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
! typedef union { DOUBLE value; unsigned int word[NWORDS]; } memory_double;
int
! FUNC (DOUBLE x)
{
! #ifdef KNOWN_EXPBIT0_LOCATION
/* Be careful to not do any floating-point operation on x, such as x == x,
because x may be a signaling NaN. */
! static memory_double nan = { L_(0.0) / L_(0.0) };
! static DOUBLE plus_inf = L_(1.0) / L_(0.0);
! static DOUBLE minus_inf = -L_(1.0) / L_(0.0);
memory_double m;
/* A NaN can be recognized through its exponent. But exclude +Infinity and
-Infinity, which have the same exponent. */
m.value = x;
! if (((m.word[EXPBIT0_WORD] ^ nan.word[EXPBIT0_WORD])
! & (EXP_MASK << EXPBIT0_BIT))
== 0)
! return (memcmp (&m.value, &plus_inf, sizeof (DOUBLE)) != 0
! && memcmp (&m.value, &minus_inf, sizeof (DOUBLE)) != 0);
else
return 0;
#else
*** lib/isnanl.c 24 Feb 2007 19:15:21 -0000 1.1
--- lib/isnanl.c 25 Feb 2007 02:28:51 -0000
***************
*** 17,62 ****
/* Written by Bruno Haible <address@hidden>, 2007. */
! #include <config.h>
!
! #include <float.h>
! #include <string.h>
!
! #define LDBL_EXP_MASK ((LDBL_MAX_EXP - LDBL_MIN_EXP) | 7)
!
! #define NWORDS \
! ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
! typedef union { long double value; unsigned int word[NWORDS]; }
! memory_long_double;
!
! int
! rpl_isnanl (long double x)
! {
! #if defined LDBL_EXPBIT0_WORD && defined LDBL_EXPBIT0_BIT
! /* Be careful to not do any floating-point operation on x, such as x == x,
! because x may be a signalling NaN. */
! static memory_long_double nan = { 0.0L / 0.0L };
! static long double plus_inf = 1.0L / 0.0L;
! static long double minus_inf = -1.0L / 0.0L;
! memory_long_double m;
!
! /* A NaN can be recognized through its exponent. But exclude +Infinity and
! -Infinity, which have the same exponent. */
! m.value = x;
! if ((((m.word[LDBL_EXPBIT0_WORD] >> LDBL_EXPBIT0_BIT)
! ^ (nan.word[LDBL_EXPBIT0_WORD] >> LDBL_EXPBIT0_BIT))
! & LDBL_EXP_MASK)
! == 0)
! return (memcmp (&m.value, &plus_inf, sizeof (long double)) != 0
! && memcmp (&m.value, &minus_inf, sizeof (long double)) != 0);
! else
! return 0;
! #else
! /* The configuration did not find sufficient information. Give up about
! the signaling NaNs, handle only the quiet NaNs. */
! if (x == x)
! return 0;
! else
! return 1;
! #endif
! }
--- 17,21 ----
/* Written by Bruno Haible <address@hidden>, 2007. */
! #define USE_LONG_DOUBLE
! #include "isnan.c"
*** modules/isnanl-nolibm 24 Feb 2007 19:15:21 -0000 1.1
--- modules/isnanl-nolibm 25 Feb 2007 02:28:51 -0000
***************
*** 4,9 ****
--- 4,10 ----
Files:
lib/isnanl.h
lib/isnanl.c
+ lib/isnan.c
m4/isnanl.m4
m4/longdouble.m4