mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-14 08:16:24 +01:00
Merge branch 'gnulib.msvc.fixes' into 'master'
Fix gnulib build on older Visual Studio builds See merge request GNOME/glib!757
This commit is contained in:
commit
7c584260fc
@ -44,7 +44,8 @@ To update:
|
|||||||
* Run gnulib-tool --lgpl=2 --import --lib=libgnu --source-base=lib \
|
* Run gnulib-tool --lgpl=2 --import --lib=libgnu --source-base=lib \
|
||||||
--m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. \
|
--m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. \
|
||||||
--no-conditional-dependencies --no-libtool --macro-prefix=gl \
|
--no-conditional-dependencies --no-libtool --macro-prefix=gl \
|
||||||
isnand-nolibm isnanl-nolibm printf-frexpl vasnprintf
|
isnand-nolibm isnanf-nolibm isnanl-nolibm printf-frexpl \
|
||||||
|
signbit vasnprintf
|
||||||
* Then pick out the files that are already in glib/gnulib subdirectory
|
* Then pick out the files that are already in glib/gnulib subdirectory
|
||||||
(the rest of the files are not needed):
|
(the rest of the files are not needed):
|
||||||
|
|
||||||
@ -56,6 +57,8 @@ gnulib_math.h.in (rename from math.in.h)
|
|||||||
isnan.c
|
isnan.c
|
||||||
isnand.c
|
isnand.c
|
||||||
isnand-nolibm.h
|
isnand-nolibm.h
|
||||||
|
isnanf.c
|
||||||
|
isnanf-nolibm.h
|
||||||
isnanl.c
|
isnanl.c
|
||||||
isnanl-nolibm.h
|
isnanl-nolibm.h
|
||||||
printf-args.c
|
printf-args.c
|
||||||
@ -66,6 +69,9 @@ printf-frexpl.c
|
|||||||
printf-frexpl.h
|
printf-frexpl.h
|
||||||
printf-parse.c
|
printf-parse.c
|
||||||
printf-parse.h
|
printf-parse.h
|
||||||
|
signbitd.c
|
||||||
|
signbitf.c
|
||||||
|
signbitl.c
|
||||||
vasnprintf.c
|
vasnprintf.c
|
||||||
vasnprintf.h
|
vasnprintf.h
|
||||||
verify.h
|
verify.h
|
||||||
|
@ -14,6 +14,8 @@ long double rpl_frexpl (long double x, int *expptr)
|
|||||||
return x;
|
return x;
|
||||||
else if (isinf (x))
|
else if (isinf (x))
|
||||||
return x;
|
return x;
|
||||||
|
#ifndef _MSC_VER
|
||||||
#undef frexpl
|
#undef frexpl
|
||||||
|
#endif
|
||||||
return frexpl (x, expptr);
|
return frexpl (x, expptr);
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,11 @@ extern
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
"C"
|
"C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined (_MSC_VER) || defined (TEST_FREXPL_DECL)
|
||||||
long double frexpl (long double, int *);
|
long double frexpl (long double, int *);
|
||||||
|
#endif
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
@ -128,3 +132,11 @@ else
|
|||||||
gl_cv_func_frexpl_broken_beyond_repair = false
|
gl_cv_func_frexpl_broken_beyond_repair = false
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
frexpl_test_decl = '''
|
||||||
|
#define TEST_FREXPL_DECL 1
|
||||||
|
''' + frexpl_test
|
||||||
|
|
||||||
|
build_result = cc.compiles(frexpl_test_decl,
|
||||||
|
name : 'frexpl prototype can be re-listed')
|
||||||
|
gl_cv_func_frexpl_decl = build_result
|
||||||
|
@ -9,7 +9,11 @@ extern
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
"C"
|
"C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined (_MSC_VER) || defined (TEST_LDEXPL_DECL)
|
||||||
long double ldexpl (long double, int);
|
long double ldexpl (long double, int);
|
||||||
|
#endif
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
@ -43,3 +47,11 @@ else
|
|||||||
gl_cv_func_ldexpl_works = true
|
gl_cv_func_ldexpl_works = true
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ldexpl_test_decl = '''
|
||||||
|
#define TEST_LDEXPL_DECL 1
|
||||||
|
''' + ldexpl_test
|
||||||
|
|
||||||
|
build_result = cc.compiles(ldexpl_test_decl,
|
||||||
|
name : 'ldexpl prototype can be re-listed')
|
||||||
|
gl_cv_func_ldexpl_decl = build_result
|
||||||
|
30
glib/gnulib/isinf.c
Normal file
30
glib/gnulib/isinf.c
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef _MSC_VER
|
||||||
|
#error "This implementation is currently supported for Visual Studio only!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include <gnulib_math.h>
|
||||||
|
#include <float.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
gl_isinff (float x)
|
||||||
|
{
|
||||||
|
#if defined (_WIN64) && (defined (_M_X64) || defined (_M_AMD64))
|
||||||
|
return !_finitef (x);
|
||||||
|
#else
|
||||||
|
return !_finite (x);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
gl_isinfd (double x)
|
||||||
|
{
|
||||||
|
return !_finite (x);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
gl_isinfl (long double x)
|
||||||
|
{
|
||||||
|
return gl_isinfd (x);
|
||||||
|
}
|
40
glib/gnulib/isnanf-nolibm.h
Normal file
40
glib/gnulib/isnanf-nolibm.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/* Test for NaN that does not need libm.
|
||||||
|
Copyright (C) 2007-2019 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General PublicLicense as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General PublicLicense for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General PublicLicense
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#if HAVE_ISNANF_IN_LIBC
|
||||||
|
/* Get declaration of isnan macro or (older) isnanf function. */
|
||||||
|
# include <math.h>
|
||||||
|
# if __GNUC__ >= 4
|
||||||
|
/* GCC 4.0 and newer provides three built-ins for isnan. */
|
||||||
|
# undef isnanf
|
||||||
|
# define isnanf(x) __builtin_isnanf ((float)(x))
|
||||||
|
# elif defined isnan
|
||||||
|
# undef isnanf
|
||||||
|
# define isnanf(x) isnan ((float)(x))
|
||||||
|
# else
|
||||||
|
/* Get declaration of isnanf(), if not declared in <math.h>. */
|
||||||
|
# if defined __sgi
|
||||||
|
/* We can't include <ieeefp.h>, because it conflicts with our definition of
|
||||||
|
isnand. Therefore declare isnanf separately. */
|
||||||
|
extern int isnanf (float x);
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
/* Test whether X is a NaN. */
|
||||||
|
# undef isnanf
|
||||||
|
# define isnanf rpl_isnanf
|
||||||
|
extern int isnanf (float x);
|
||||||
|
#endif
|
20
glib/gnulib/isnanf.c
Normal file
20
glib/gnulib/isnanf.c
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/* Test for NaN that does not need libm.
|
||||||
|
Copyright (C) 2007, 2009-2019 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General PublicLicense as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General PublicLicense for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General PublicLicense
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
|
||||||
|
|
||||||
|
#define USE_FLOAT
|
||||||
|
#include "isnan.c"
|
@ -51,10 +51,6 @@ unneeded_funcs = [
|
|||||||
'ILOGB',
|
'ILOGB',
|
||||||
'ILOGBF',
|
'ILOGBF',
|
||||||
'ILOGBL',
|
'ILOGBL',
|
||||||
'ISFINITE',
|
|
||||||
'ISINF',
|
|
||||||
'ISNAN',
|
|
||||||
'ISNANF',
|
|
||||||
'LDEXPF',
|
'LDEXPF',
|
||||||
'LOG',
|
'LOG',
|
||||||
'LOG10',
|
'LOG10',
|
||||||
@ -84,7 +80,6 @@ unneeded_funcs = [
|
|||||||
'ROUND',
|
'ROUND',
|
||||||
'ROUNDF',
|
'ROUNDF',
|
||||||
'ROUNDL',
|
'ROUNDL',
|
||||||
'SIGNBIT',
|
|
||||||
'SINF',
|
'SINF',
|
||||||
'SINHF',
|
'SINHF',
|
||||||
'SINL',
|
'SINL',
|
||||||
@ -110,9 +105,14 @@ endforeach
|
|||||||
needed_funcs = [
|
needed_funcs = [
|
||||||
'FREXP',
|
'FREXP',
|
||||||
'FREXPL',
|
'FREXPL',
|
||||||
|
'ISFINITE',
|
||||||
|
'ISINF',
|
||||||
|
'ISNAN',
|
||||||
'ISNAND',
|
'ISNAND',
|
||||||
|
'ISNANF',
|
||||||
'ISNANL',
|
'ISNANL',
|
||||||
'LDEXPL',
|
'LDEXPL',
|
||||||
|
'SIGNBIT',
|
||||||
]
|
]
|
||||||
|
|
||||||
foreach f : needed_funcs
|
foreach f : needed_funcs
|
||||||
@ -282,6 +282,7 @@ endif
|
|||||||
|
|
||||||
math_h_config.set ('REPLACE_FREXP', gl_cv_func_frexp_works ? 0 : 1)
|
math_h_config.set ('REPLACE_FREXP', gl_cv_func_frexp_works ? 0 : 1)
|
||||||
math_h_config.set ('REPLACE_FREXPL', gl_cv_func_frexpl_works ? 0 : 1)
|
math_h_config.set ('REPLACE_FREXPL', gl_cv_func_frexpl_works ? 0 : 1)
|
||||||
|
math_h_config.set ('HAVE_DECL_FREXPL', gl_cv_func_frexpl_decl ? 0 : 1)
|
||||||
|
|
||||||
math_h_config.set ('REPLACE_ITOLD', 0)
|
math_h_config.set ('REPLACE_ITOLD', 0)
|
||||||
math_h_config.set ('REPLACE_HUGE_VAL', 0)
|
math_h_config.set ('REPLACE_HUGE_VAL', 0)
|
||||||
@ -293,6 +294,30 @@ else
|
|||||||
gl_cv_func_ldexpl_works = false
|
gl_cv_func_ldexpl_works = false
|
||||||
endif
|
endif
|
||||||
math_h_config.set ('REPLACE_LDEXPL', gl_cv_func_ldexpl_works ? 0 : 1)
|
math_h_config.set ('REPLACE_LDEXPL', gl_cv_func_ldexpl_works ? 0 : 1)
|
||||||
|
math_h_config.set ('HAVE_DECL_LDEXPL', gl_cv_func_ldexpl_decl ? 0 : 1)
|
||||||
|
|
||||||
|
inf_tmpl = '''#include <math.h>
|
||||||
|
double x;
|
||||||
|
int main () {return @0@ (x);}
|
||||||
|
'''
|
||||||
|
|
||||||
|
other_needed_math_sources = []
|
||||||
|
# Some compilers may not have isfinite, isinf available
|
||||||
|
foreach f: ['isfinite', 'isinf', 'isnan', 'isnanf', 'signbit']
|
||||||
|
links = cc.links (inf_tmpl.format('@0@'.format(f)),
|
||||||
|
dependencies : [libm])
|
||||||
|
math_h_config.set ('HAVE_@0@'.format(f.to_upper()), links ? 1 : 0)
|
||||||
|
math_h_config.set ('HAVE_@0@_IN_LIBC'.format(f.to_upper()), links ? 1 : 0)
|
||||||
|
math_h_config.set ('REPLACE_@0@'.format(f.to_upper()), links ? 0 : 1)
|
||||||
|
set_variable ('have_@0@'.format(f), links)
|
||||||
|
if not links
|
||||||
|
if f == 'signbit'
|
||||||
|
other_needed_math_sources += [ 'signbitd.c', 'signbitf.c', 'signbitl.c' ]
|
||||||
|
elif f != 'isfinite' and f != 'isnan'
|
||||||
|
other_needed_math_sources += [ '@0@.c'.format(f) ]
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endforeach
|
||||||
|
|
||||||
math_h = configure_file (input: 'gnulib_math.h.in',
|
math_h = configure_file (input: 'gnulib_math.h.in',
|
||||||
output: 'gnulib_math.h',
|
output: 'gnulib_math.h',
|
||||||
@ -307,6 +332,8 @@ if not gl_cv_func_frexpl_works
|
|||||||
gnulib_sources += ['frexpl.c']
|
gnulib_sources += ['frexpl.c']
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
gnulib_sources += other_needed_math_sources
|
||||||
|
|
||||||
gnulib_lib = static_library('gnulib', gnulib_sources,
|
gnulib_lib = static_library('gnulib', gnulib_sources,
|
||||||
dependencies : [libm],
|
dependencies : [libm],
|
||||||
include_directories : [configinc, glibinc, include_directories ('.')],
|
include_directories : [configinc, glibinc, include_directories ('.')],
|
||||||
|
64
glib/gnulib/signbitd.c
Normal file
64
glib/gnulib/signbitd.c
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/* signbit() macro: Determine the sign bit of a floating-point number.
|
||||||
|
Copyright (C) 2007-2019 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General PublicLicense as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General PublicLicense for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General PublicLicense
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
/* Specification. */
|
||||||
|
#include <gnulib_math.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "isnand-nolibm.h"
|
||||||
|
#include "float+.h"
|
||||||
|
|
||||||
|
#ifdef gl_signbitd_OPTIMIZED_MACRO
|
||||||
|
# undef gl_signbitd
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
gl_signbitd (double arg)
|
||||||
|
{
|
||||||
|
#if defined DBL_SIGNBIT_WORD && defined DBL_SIGNBIT_BIT
|
||||||
|
/* The use of a union to extract the bits of the representation of a
|
||||||
|
'long double' is safe in practice, despite of the "aliasing rules" of
|
||||||
|
C99, because the GCC docs say
|
||||||
|
"Even with '-fstrict-aliasing', type-punning is allowed, provided the
|
||||||
|
memory is accessed through the union type."
|
||||||
|
and similarly for other compilers. */
|
||||||
|
# define NWORDS \
|
||||||
|
((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
|
||||||
|
union { double value; unsigned int word[NWORDS]; } m;
|
||||||
|
m.value = arg;
|
||||||
|
return (m.word[DBL_SIGNBIT_WORD] >> DBL_SIGNBIT_BIT) & 1;
|
||||||
|
#elif HAVE_COPYSIGN_IN_LIBC
|
||||||
|
return copysign (1.0, arg) < 0;
|
||||||
|
#else
|
||||||
|
/* This does not do the right thing for NaN, but this is irrelevant for
|
||||||
|
most use cases. */
|
||||||
|
if (isnand (arg))
|
||||||
|
return 0;
|
||||||
|
if (arg < 0.0)
|
||||||
|
return 1;
|
||||||
|
else if (arg == 0.0)
|
||||||
|
{
|
||||||
|
/* Distinguish 0.0 and -0.0. */
|
||||||
|
static double plus_zero = 0.0;
|
||||||
|
double arg_mem = arg;
|
||||||
|
return (memcmp (&plus_zero, &arg_mem, SIZEOF_DBL) != 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
64
glib/gnulib/signbitf.c
Normal file
64
glib/gnulib/signbitf.c
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/* signbit() macro: Determine the sign bit of a floating-point number.
|
||||||
|
Copyright (C) 2007, 2009-2019 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General PublicLicense as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General PublicLicense for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General PublicLicense
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
/* Specification. */
|
||||||
|
#include <gnulib_math.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "isnanf-nolibm.h"
|
||||||
|
#include "float+.h"
|
||||||
|
|
||||||
|
#ifdef gl_signbitf_OPTIMIZED_MACRO
|
||||||
|
# undef gl_signbitf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
gl_signbitf (float arg)
|
||||||
|
{
|
||||||
|
#if defined FLT_SIGNBIT_WORD && defined FLT_SIGNBIT_BIT
|
||||||
|
/* The use of a union to extract the bits of the representation of a
|
||||||
|
'long double' is safe in practice, despite of the "aliasing rules" of
|
||||||
|
C99, because the GCC docs say
|
||||||
|
"Even with '-fstrict-aliasing', type-punning is allowed, provided the
|
||||||
|
memory is accessed through the union type."
|
||||||
|
and similarly for other compilers. */
|
||||||
|
# define NWORDS \
|
||||||
|
((sizeof (float) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
|
||||||
|
union { float value; unsigned int word[NWORDS]; } m;
|
||||||
|
m.value = arg;
|
||||||
|
return (m.word[FLT_SIGNBIT_WORD] >> FLT_SIGNBIT_BIT) & 1;
|
||||||
|
#elif HAVE_COPYSIGNF_IN_LIBC
|
||||||
|
return copysignf (1.0f, arg) < 0;
|
||||||
|
#else
|
||||||
|
/* This does not do the right thing for NaN, but this is irrelevant for
|
||||||
|
most use cases. */
|
||||||
|
if (isnanf (arg))
|
||||||
|
return 0;
|
||||||
|
if (arg < 0.0f)
|
||||||
|
return 1;
|
||||||
|
else if (arg == 0.0f)
|
||||||
|
{
|
||||||
|
/* Distinguish 0.0f and -0.0f. */
|
||||||
|
static float plus_zero = 0.0f;
|
||||||
|
float arg_mem = arg;
|
||||||
|
return (memcmp (&plus_zero, &arg_mem, SIZEOF_FLT) != 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
64
glib/gnulib/signbitl.c
Normal file
64
glib/gnulib/signbitl.c
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/* signbit() macro: Determine the sign bit of a floating-point number.
|
||||||
|
Copyright (C) 2007, 2009-2019 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General PublicLicense as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General PublicLicense for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General PublicLicense
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
/* Specification. */
|
||||||
|
#include <gnulib_math.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "isnanl-nolibm.h"
|
||||||
|
#include "float+.h"
|
||||||
|
|
||||||
|
#ifdef gl_signbitl_OPTIMIZED_MACRO
|
||||||
|
# undef gl_signbitl
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
gl_signbitl (long double arg)
|
||||||
|
{
|
||||||
|
#if defined LDBL_SIGNBIT_WORD && defined LDBL_SIGNBIT_BIT
|
||||||
|
/* The use of a union to extract the bits of the representation of a
|
||||||
|
'long double' is safe in practice, despite of the "aliasing rules" of
|
||||||
|
C99, because the GCC docs say
|
||||||
|
"Even with '-fstrict-aliasing', type-punning is allowed, provided the
|
||||||
|
memory is accessed through the union type."
|
||||||
|
and similarly for other compilers. */
|
||||||
|
# define NWORDS \
|
||||||
|
((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
|
||||||
|
union { long double value; unsigned int word[NWORDS]; } m;
|
||||||
|
m.value = arg;
|
||||||
|
return (m.word[LDBL_SIGNBIT_WORD] >> LDBL_SIGNBIT_BIT) & 1;
|
||||||
|
#elif HAVE_COPYSIGNL_IN_LIBC
|
||||||
|
return copysignl (1.0L, arg) < 0;
|
||||||
|
#else
|
||||||
|
/* This does not do the right thing for NaN, but this is irrelevant for
|
||||||
|
most use cases. */
|
||||||
|
if (isnanl (arg))
|
||||||
|
return 0;
|
||||||
|
if (arg < 0.0L)
|
||||||
|
return 1;
|
||||||
|
else if (arg == 0.0L)
|
||||||
|
{
|
||||||
|
/* Distinguish 0.0L and -0.0L. */
|
||||||
|
static long double plus_zero = 0.0L;
|
||||||
|
long double arg_mem = arg;
|
||||||
|
return (memcmp (&plus_zero, &arg_mem, SIZEOF_LDBL) != 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user