Mercurial > hg > octave-lojdl > gnulib-hg
annotate lib/signbitl.c @ 8659:d6d05661430a
Use copysign when implementing signbit, if the libc has it already.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Tue, 10 Apr 2007 21:38:36 +0000 |
parents | 9aabfa2b3200 |
children | bbbbbf4cd1c5 |
rev | line source |
---|---|
8652 | 1 /* signbit() macro: Determine the sign bit of a floating-point number. |
2 Copyright (C) 2007 Free Software Foundation, Inc. | |
3 | |
4 This program is free software; you can redistribute it and/or modify | |
5 it under the terms of the GNU General Public License as published by | |
6 the Free Software Foundation; either version 2, or (at your option) | |
7 any later version. | |
8 | |
9 This program is distributed in the hope that it will be useful, | |
10 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 GNU General Public License for more details. | |
13 | |
14 You should have received a copy of the GNU General Public License along | |
15 with this program; if not, write to the Free Software Foundation, | |
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ | |
17 | |
18 #include <config.h> | |
19 | |
20 /* Specification. */ | |
21 #include <math.h> | |
22 | |
23 #include <string.h> | |
24 #include "isnanl-nolibm.h" | |
25 #include "float+.h" | |
26 | |
27 #undef gl_signbitl | |
28 | |
29 int | |
30 gl_signbitl (long double arg) | |
31 { | |
32 #if defined LDBL_SIGNBIT_WORD && defined LDBL_SIGNBIT_BIT | |
8659
d6d05661430a
Use copysign when implementing signbit, if the libc has it already.
Bruno Haible <bruno@clisp.org>
parents:
8652
diff
changeset
|
33 /* The use of a union to extract the bits of the representation of a |
d6d05661430a
Use copysign when implementing signbit, if the libc has it already.
Bruno Haible <bruno@clisp.org>
parents:
8652
diff
changeset
|
34 'long double' is safe in practice, despite of the "aliasing rules" of |
d6d05661430a
Use copysign when implementing signbit, if the libc has it already.
Bruno Haible <bruno@clisp.org>
parents:
8652
diff
changeset
|
35 C99, because the GCC docs say |
d6d05661430a
Use copysign when implementing signbit, if the libc has it already.
Bruno Haible <bruno@clisp.org>
parents:
8652
diff
changeset
|
36 "Even with '-fstrict-aliasing', type-punning is allowed, provided the |
d6d05661430a
Use copysign when implementing signbit, if the libc has it already.
Bruno Haible <bruno@clisp.org>
parents:
8652
diff
changeset
|
37 memory is accessed through the union type." |
d6d05661430a
Use copysign when implementing signbit, if the libc has it already.
Bruno Haible <bruno@clisp.org>
parents:
8652
diff
changeset
|
38 and similarly for other compilers. */ |
8652 | 39 # define NWORDS \ |
40 ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) | |
41 union { long double value; unsigned int word[NWORDS]; } m; | |
42 m.value = arg; | |
43 return (m.word[LDBL_SIGNBIT_WORD] >> LDBL_SIGNBIT_BIT) & 1; | |
8659
d6d05661430a
Use copysign when implementing signbit, if the libc has it already.
Bruno Haible <bruno@clisp.org>
parents:
8652
diff
changeset
|
44 #elif HAVE_COPYSIGNL_IN_LIBC |
d6d05661430a
Use copysign when implementing signbit, if the libc has it already.
Bruno Haible <bruno@clisp.org>
parents:
8652
diff
changeset
|
45 return copysignl (1.0L, arg) < 0; |
8652 | 46 #else |
47 /* This does not do the right thing for NaN, but this is irrelevant for | |
48 most use cases. */ | |
49 if (isnanl (arg)) | |
50 return 0; | |
51 if (arg < 0.0L) | |
52 return 1; | |
53 else if (arg == 0.0L) | |
54 { | |
55 /* Distinguish 0.0L and -0.0L. */ | |
56 static long double plus_zero = 0.0L; | |
57 long double arg_mem = arg; | |
58 return (memcmp (&plus_zero, &arg_mem, SIZEOF_LDBL) != 0); | |
59 } | |
60 else | |
61 return 0; | |
62 #endif | |
63 } |