X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=m4%2Fsignbit.m4;h=6973a7110787b52b4b029c3b30c8936b76973402;hb=258036d8674583fce2002a04afc996f18c8b8486;hp=1751253944ebce2042079c2f8d421051cf6a08cc;hpb=64865499c9cf8748356a0857a8481d74b394bd79;p=gnulib.git diff --git a/m4/signbit.m4 b/m4/signbit.m4 index 175125394..6973a7110 100644 --- a/m4/signbit.m4 +++ b/m4/signbit.m4 @@ -1,5 +1,5 @@ -# signbit.m4 serial 7 -dnl Copyright (C) 2007-2010 Free Software Foundation, Inc. +# signbit.m4 serial 9 +dnl Copyright (C) 2007-2011 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -160,7 +160,8 @@ long double m0l = -LDBL_MIN * LDBL_MIN; #else long double m0l = -p0l; #endif - if (signbit (vf)) + int result = 0; + if (signbit (vf)) /* link check */ vf++; { float plus_inf = 1.0f / p0f; @@ -171,9 +172,9 @@ long double m0l = -p0l; && (memcmp (&m0f, &p0f, sizeof (float)) == 0 || signbit (m0f)) && !signbit (plus_inf) && signbit (minus_inf))) - return 1; + result |= 1; } - if (signbit (vd)) + if (signbit (vd)) /* link check */ vd++; { double plus_inf = 1.0 / p0d; @@ -184,22 +185,27 @@ long double m0l = -p0l; && (memcmp (&m0d, &p0d, sizeof (double)) == 0 || signbit (m0d)) && !signbit (plus_inf) && signbit (minus_inf))) - return 1; + result |= 2; } - if (signbit (vl)) + if (signbit (vl)) /* link check */ vl++; { long double plus_inf = 1.0L / p0l; long double minus_inf = -1.0L / p0l; - if (!(!signbit (255.0L) - && signbit (-255.0L) - && !signbit (p0l) - && (memcmp (&m0l, &p0l, sizeof (long double)) == 0 || signbit (m0l)) - && !signbit (plus_inf) - && signbit (minus_inf))) - return 1; + if (signbit (255.0L)) + result |= 4; + if (!signbit (-255.0L)) + result |= 4; + if (signbit (p0l)) + result |= 8; + if (!(memcmp (&m0l, &p0l, sizeof (long double)) == 0 || signbit (m0l))) + result |= 16; + if (signbit (plus_inf)) + result |= 32; + if (!signbit (minus_inf)) + result |= 64; } - return 0; + return result; } ]]) @@ -249,7 +255,7 @@ int main () { /* More than one bit difference. */ fprintf (fp, "unknown"); - return 1; + return 2; } if (x) { @@ -261,7 +267,7 @@ int main () { /* No difference. */ fprintf (fp, "unknown"); - return 1; + return 3; } /* Now m = plus.word[k] ^ ~minus.word[k]. */ if (plus.word[k] & ~minus.word[k]) @@ -269,13 +275,15 @@ int main () /* Oh? The sign bit is set in the positive and cleared in the negative numbers? */ fprintf (fp, "unknown"); - return 1; + return 4; } for (i = 0; ; i++) if ((m >> i) & 1) break; fprintf (fp, "word %d bit %d", (int) k, (int) i); - return (fclose (fp) != 0); + if (fclose (fp) != 0) + return 5; + return 0; } ]])], [$2=`cat conftest.out`], @@ -298,3 +306,43 @@ int main () ;; esac ]) + +# Expands to code that defines a function signbitf(float). +# It extracts the sign bit of a non-NaN value. +AC_DEFUN([gl_FLOAT_SIGNBIT_CODE], +[ + gl_FLOATTYPE_SIGNBIT_CODE([float], [f], [f]) +]) + +# Expands to code that defines a function signbitd(double). +# It extracts the sign bit of a non-NaN value. +AC_DEFUN([gl_DOUBLE_SIGNBIT_CODE], +[ + gl_FLOATTYPE_SIGNBIT_CODE([double], [d], []) +]) + +# Expands to code that defines a function signbitl(long double). +# It extracts the sign bit of a non-NaN value. +AC_DEFUN([gl_LONG_DOUBLE_SIGNBIT_CODE], +[ + gl_FLOATTYPE_SIGNBIT_CODE([long double], [l], [L]) +]) + +AC_DEFUN([gl_FLOATTYPE_SIGNBIT_CODE], +[[ +static int +signbit$2 ($1 value) +{ + typedef union { $1 f; unsigned char b[sizeof ($1)]; } float_union; + static float_union plus_one = { 1.0$3 }; /* unused bits are zero here */ + static float_union minus_one = { -1.0$3 }; /* unused bits are zero here */ + /* Compute the sign bit mask as the XOR of plus_one and minus_one. */ + float_union u; + unsigned int i; + u.f = value; + for (i = 0; i < sizeof ($1); i++) + if (u.b[i] & (plus_one.b[i] ^ minus_one.b[i])) + return 1; + return 0; +} +]])