1
0
mirror of https://github.com/adtools/clib2.git synced 2025-12-08 14:59:05 +00:00

- For the printf() "%a" conversion the exponent now comes out as a binary

number rather than a decimal one. Now how odd is that?

- strtod() and strtof() now support "inf"/"infinity"/"nan"/"nan(..)" and
  hexadecimal floating point numbers, for C99.

- Added the fpclassify(), isfinite(), isnormal() and signbit() macros for C99.

- Reimplemented isnan() and isinf() as macros for C99. The corresponding
  functions will be dropped from the library. Note that the isinf() macro
  does not return -1, 0 or 1 like the old function did, but only 0 or 1
  depending upon whether the parameter represents +/- infinity or not.

- Added fabsf() for C99.


git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@14935 87f5fb63-7c3d-0410-a384-fd976d0f7a62
This commit is contained in:
Olaf Barthel
2005-05-08 08:51:30 +00:00
parent c8d29ea9c1
commit 9e32991a6d
15 changed files with 1007 additions and 291 deletions

View File

@ -1,5 +1,5 @@
#
# $Id: GNUmakefile.68k,v 1.51 2005-05-07 17:03:55 obarthel Exp $
# $Id: GNUmakefile.68k,v 1.52 2005-05-08 08:51:29 obarthel Exp $
#
# :ts=8
#
@ -523,20 +523,24 @@ MATH_LIB = \
math_cosh.o \
math_exp.o \
math_fabs.o \
math_fabsf.o \
math_floor.o \
math_fmod.o \
math_fpclassify.o \
math_isfinite.o \
math_signbit.o \
math_frexp.o \
math_huge_val.o \
math_huge_valf.o \
math_hypot.o \
math_init_exit.o \
math_isinf.o \
math_isnan.o \
math_ldexp.o \
math_log.o \
math_log10.o \
math_logb.o \
math_modf.o \
math_nan.o \
math_nanf.o \
math_pow.o \
math_rint.o \
math_rintf.o \

View File

@ -1,5 +1,5 @@
#
# $Id: GNUmakefile.os4,v 1.54 2005-05-07 17:03:55 obarthel Exp $
# $Id: GNUmakefile.os4,v 1.55 2005-05-08 08:51:29 obarthel Exp $
#
# :ts=8
#
@ -523,20 +523,24 @@ MATH_LIB = \
math_cosh.o \
math_exp.o \
math_fabs.o \
math_fabsf.o \
math_floor.o \
math_fmod.o \
math_fpclassify.o \
math_isfinite.o \
math_signbit.o \
math_frexp.o \
math_huge_val.o \
math_huge_valf.o \
math_hypot.o \
math_init_exit.o \
math_isnan.o \
math_isinf.o \
math_ldexp.o \
math_log.o \
math_log10.o \
math_logb.o \
math_modf.o \
math_nan.o \
math_nanf.o \
math_pow.o \
math_rint.o \
math_rintf.o \

View File

@ -29,12 +29,27 @@
And it ignores the E and O modifiers.
- The printf() family now supports the %hh, %j, %t and %z modifiers and the
%a/%A conversions for C99. The %j is treated like %ll, %t and %z are treated
%a/%A conversions for C99. The %j is treated like %ll; %t and %z are treated
like %l. Also, the "infinity"/"not a number" signals now come out as the
strings "inf" and "nan".
- Added HUGE_VALF to <math.h>.
- For the printf() "%a" conversion the exponent now comes out as a binary
number rather than a decimal one. Now how odd is that?
- strtod() and strtof() now support "inf"/"infinity"/"nan"/"nan(..)" and
hexadecimal floating point numbers, for C99.
- Added the fpclassify(), isfinite(), isnormal() and signbit() macros for C99.
- Reimplemented isnan() and isinf() as macros for C99. The corresponding
functions will be dropped from the library. Note that the isinf() macro
does not return -1, 0 or 1 like the old function did, but only 0 or 1
depending upon whether the parameter represents +/- infinity or not.
- Added fabsf() for C99.
c.lib 1.191 (9.4.2005)

View File

@ -1,5 +1,5 @@
/*
* $Id: math.h,v 1.7 2005-05-07 17:04:07 obarthel Exp $
* $Id: math.h,v 1.8 2005-05-08 08:51:30 obarthel Exp $
*
* :ts=4
*
@ -103,8 +103,6 @@ extern double tanh(double x);
extern double rint(double x);
extern float rintf(float x);
extern int isinf(double x);
extern int isnan(double x);
extern double logb(double x);
extern double hypot(double x,double y);
@ -123,6 +121,51 @@ extern float __huge_val_float;
/****************************************************************************/
#define FP_INFINITE 0 /* -/+ infinity */
#define FP_NAN 1 /* not a number */
#define FP_NORMAL 2 /* normalized floating point number */
#define FP_SUBNORMAL 3 /* very small floating point number; special
case of IEEE 754 */
#define FP_ZERO 4 /* exponent/fraction are zero */
/****************************************************************************/
extern int __fpclassify_float(float x);
extern int __fpclassify_double(double x);
extern int __isfinite_float(float x);
extern int __isfinite_double(double x);
extern int __signbit_float(float x);
extern int __signbit_double(double x);
#define fpclassify(x) \
((sizeof(x) == sizeof(float)) ? __fpclassify_float(x) : __fpclassify_double(x))
#define isfinite(x) \
((sizeof(x) == sizeof(float)) ? __isfinite_single(x) : __isfinite_double(x))
#define isinf(x) \
(((sizeof(x) == sizeof(float)) ? __fpclassify_float(x) : __fpclassify_double(x)) == FP_INFINITE)
#define isnan(x) \
(((sizeof(x) == sizeof(float)) ? __fpclassify_float(x) : __fpclassify_double(x)) == FP_NAN)
#define isnormal(x) \
(((sizeof(x) == sizeof(float)) ? __fpclassify_float(x) : __fpclassify_double(x)) == FP_NORMAL)
#define signbit(x) \
((sizeof(x) == sizeof(float)) ? __signbit_single(x) : __signbit_double(x))
/****************************************************************************/
extern float fabsf(float x);
/****************************************************************************/
extern float nanf(const char *tagp);
extern double nan(const char *tagp);
/****************************************************************************/
#ifdef __cplusplus
}
#endif /* __cplusplus */

142
library/math_fabsf.c Normal file
View File

@ -0,0 +1,142 @@
/*
* $Id: math_fabsf.c,v 1.1 2005-05-08 08:51:29 obarthel Exp $
*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2005 by Olaf Barthel <olsen@sourcery.han.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MATH_HEADERS_H
#include "math_headers.h"
#endif /* _MATH_HEADERS_H */
/****************************************************************************/
#if defined(FLOATING_POINT_SUPPORT)
/****************************************************************************/
#if defined(IEEE_FLOATING_POINT_SUPPORT)
/****************************************************************************/
#if defined(__GNUC__)
/****************************************************************************/
#if defined(SMALL_DATA)
#define A4(x) "a4@(" #x ":W)"
#elif defined(SMALL_DATA32)
#define A4(x) "a4@(" #x ":L)"
#else
#define A4(x) #x
#endif /* SMALL_DATA */
/****************************************************************************/
extern float __fabsf(float x);
/****************************************************************************/
asm("
.text
.even
.globl _MathIeeeSingBasBase
.globl ___fabsf
___fabsf:
movel a6,sp@-
movel "A4(_MathIeeeSingBasBase)",a6
moveml sp@(8),d0/d1
jsr a6@(-54:W)
movel sp@+,a6
rts
");
/****************************************************************************/
#else
/****************************************************************************/
INLINE STATIC const float
__fabsf(float x)
{
float result;
result = IEEESPAbs(x);
return(result);
}
/****************************************************************************/
#endif /* __GNUC__ */
/****************************************************************************/
#else
/****************************************************************************/
INLINE STATIC const float
__fabsf(float number)
{
union ieee_single x;
x.value = number;
/* Knock off the sign bit. */
x.raw[0] &= 0x7fffffff;
return(x.value);
}
/****************************************************************************/
#endif /* IEEE_FLOATING_POINT_SUPPORT */
/****************************************************************************/
float
fabsf(float x)
{
float result;
result = __fabsf(x);
return(result);
}
/****************************************************************************/
#endif /* FLOATING_POINT_SUPPORT */

97
library/math_fpclassify.c Normal file
View File

@ -0,0 +1,97 @@
/*
* $Id: math_fpclassify.c,v 1.1 2005-05-08 08:51:29 obarthel Exp $
*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2005 by Olaf Barthel <olsen@sourcery.han.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _STDIO_HEADERS_H
#include "stdio_headers.h"
#endif /* _STDIO_HEADERS_H */
/****************************************************************************/
#if defined (FLOATING_POINT_SUPPORT)
/****************************************************************************/
/* The following is not part of the ISO 'C' (1994) standard, but it should
be part of ISO/IEC 9899:1999, also known as "C99". */
/****************************************************************************/
int
__fpclassify_float(float number)
{
union ieee_single x;
int result;
x.value = number;
if((x.raw[0] & 0x7f800000) == 0x7f800000 && (x.raw[0] & 0x007fffff) != 0)
result = FP_NAN; /* Exponent = 255 and fraction != 0.0 -> not a number */
else if ((x.raw[0] & 0x7fffffff) == 0x7f800000)
result = FP_INFINITE; /* Exponent = 255 and fraction = 0.0 -> infinity */
else if (x.raw[0] == 0) /* ZZZ test against epsilon? */
result = FP_ZERO; /* Both exponent and fraction are zero -> zero */
else if ((x.raw[0] & 0x7f800000) == 0)
result = FP_SUBNORMAL; /* Exponent = 0 -> subnormal */
else
result = FP_NORMAL;
return(result);
}
/****************************************************************************/
int
__fpclassify_double(double number)
{
union ieee_double x;
int result;
x.value = number;
if(((x.raw[0] & 0x7ff00000) == 0x7ff00000) && ((x.raw[0] & 0x000fffff) != 0 || (x.raw[1] != 0)))
result = FP_NAN; /* Exponent = 2047 and fraction != 0.0 -> not a number */
else if (((x.raw[0] & 0x7fffffff) == 0x7ff00000) && (x.raw[1] == 0))
result = FP_INFINITE; /* Exponent = 2047 and fraction = 0.0 -> infinity */
else if (x.raw[0] == 0 && x.raw[1] == 0) /* ZZZ test against epsilon? */
result = FP_ZERO; /* Both exponent and fraction are zero -> zero */
else if ((x.raw[0] & 0x7fff0000) == 0)
result = FP_SUBNORMAL; /* Exponent = 0 -> subnormal */
else
result = FP_NORMAL;
return(result);
}
/****************************************************************************/
#endif /* FLOATING_POINT_SUPPORT */

89
library/math_isfinite.c Normal file
View File

@ -0,0 +1,89 @@
/*
* $Id: math_isfinite.c,v 1.1 2005-05-08 08:51:29 obarthel Exp $
*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2005 by Olaf Barthel <olsen@sourcery.han.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _STDIO_HEADERS_H
#include "stdio_headers.h"
#endif /* _STDIO_HEADERS_H */
/****************************************************************************/
#if defined (FLOATING_POINT_SUPPORT)
/****************************************************************************/
/* The following is not part of the ISO 'C' (1994) standard, but it should
be part of ISO/IEC 9899:1999, also known as "C99". */
/****************************************************************************/
int
__isfinite_float(float number)
{
union ieee_single x;
int result;
x.value = number;
if((x.raw[0] & 0x7f800000) == 0x7f800000 && (x.raw[0] & 0x007fffff) != 0)
result = 0; /* Exponent = 255 and fraction != 0.0 -> not a number */
else if ((x.raw[0] & 0x7fffffff) == 0x7f800000)
result = 0; /* Exponent = 255 and fraction = 0.0 -> infinity */
else
result = 1;
return(result);
}
/****************************************************************************/
int
__isfinite_double(double number)
{
union ieee_double x;
int result;
x.value = number;
if(((x.raw[0] & 0x7ff00000) == 0x7ff00000) && ((x.raw[0] & 0x000fffff) != 0 || (x.raw[1] != 0)))
result = 0; /* Exponent = 2047 and fraction != 0.0 -> not a number */
else if (((x.raw[0] & 0x7fffffff) == 0x7ff00000) && (x.raw[1] == 0))
result = 0; /* Exponent = 2047 and fraction = 0.0 -> infinity */
else
result = 1;
return(result);
}
/****************************************************************************/
#endif /* FLOATING_POINT_SUPPORT */

View File

@ -1,5 +1,5 @@
/*
* $Id: math_logb.c,v 1.5 2005-02-25 10:14:21 obarthel Exp $
* $Id: math_logb.c,v 1.6 2005-05-08 08:51:29 obarthel Exp $
*
* :ts=4
*
@ -99,8 +99,6 @@ logb(double x)
{
double result;
int sign;
if(x == 0.0)
{
result = -__get_huge_val();
@ -113,10 +111,9 @@ logb(double x)
goto out;
}
sign = isinf(x);
if(sign != 0)
if(isinf(x))
{
if(sign < 0)
if(x < 0)
result = (-x);
else
result = x;

63
library/math_nan.c Normal file
View File

@ -0,0 +1,63 @@
/*
* $Id: math_nan.c,v 1.1 2005-05-08 08:51:29 obarthel Exp $
*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2005 by Olaf Barthel <olsen@sourcery.han.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _STDIO_HEADERS_H
#include "stdio_headers.h"
#endif /* _STDIO_HEADERS_H */
/****************************************************************************/
#if defined (FLOATING_POINT_SUPPORT)
/****************************************************************************/
/* The following is not part of the ISO 'C' (1994) standard, but it should
be part of ISO/IEC 9899:1999, also known as "C99". */
/****************************************************************************/
double
nan(const char * UNUSED tagp)
{
union ieee_double x;
/* Exponent = 2047 and fraction != 0.0 */
x.raw[0] = 0x7ff00000;
x.raw[1] = 0x00000001;
return(x.value);
}
/****************************************************************************/
#endif /* FLOATING_POINT_SUPPORT */

62
library/math_nanf.c Normal file
View File

@ -0,0 +1,62 @@
/*
* $Id: math_nanf.c,v 1.1 2005-05-08 08:51:29 obarthel Exp $
*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2005 by Olaf Barthel <olsen@sourcery.han.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _STDIO_HEADERS_H
#include "stdio_headers.h"
#endif /* _STDIO_HEADERS_H */
/****************************************************************************/
#if defined (FLOATING_POINT_SUPPORT)
/****************************************************************************/
/* The following is not part of the ISO 'C' (1994) standard, but it should
be part of ISO/IEC 9899:1999, also known as "C99". */
/****************************************************************************/
float
nanf(const char * UNUSED tagp)
{
union ieee_single x;
/* Exponent = 255 and fraction != 0.0 */
x.raw[0] = 0x7f800001;
return(x.value);
}
/****************************************************************************/
#endif /* FLOATING_POINT_SUPPORT */

79
library/math_signbit.c Normal file
View File

@ -0,0 +1,79 @@
/*
* $Id: math_signbit.c,v 1.1 2005-05-08 08:51:29 obarthel Exp $
*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2005 by Olaf Barthel <olsen@sourcery.han.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _STDIO_HEADERS_H
#include "stdio_headers.h"
#endif /* _STDIO_HEADERS_H */
/****************************************************************************/
#if defined (FLOATING_POINT_SUPPORT)
/****************************************************************************/
/* The following is not part of the ISO 'C' (1994) standard, but it should
be part of ISO/IEC 9899:1999, also known as "C99". */
/****************************************************************************/
int
__signbit_float(float number)
{
union ieee_single x;
int result;
x.value = number;
result = ((x.raw[0] = 0x80000000) != 0);
return(result);
}
/****************************************************************************/
int
__signbit_double(double number)
{
union ieee_double x;
int result;
x.value = number;
result = ((x.raw[0] = 0x80000000) != 0);
return(result);
}
/****************************************************************************/
#endif /* FLOATING_POINT_SUPPORT */

View File

@ -1,5 +1,5 @@
#
# $Id: smakefile,v 1.39 2005-05-07 17:03:55 obarthel Exp $
# $Id: smakefile,v 1.40 2005-05-08 08:51:29 obarthel Exp $
#
# :ts=8
#
@ -187,20 +187,24 @@ MATH_OBJ = \
math_cosh.o \
math_exp.o \
math_fabs.o \
math_fabsf.o \
math_floor.o \
math_fmod.o \
math_fpclassify.o \
math_isfinite.o \
math_signbit.o \
math_frexp.o \
math_huge_val.o \
math_huge_valf.o \
math_hypot.o \
math_init_exit.o \
math_isinf.o \
math_isnan.o \
math_ldexp.o \
math_log.o \
math_log10.o \
math_logb.o \
math_modf.o \
math_nan.o \
math_nanf.o \
math_pow.o \
math_rint.o \
math_rintf.o \

View File

@ -1,5 +1,5 @@
/*
* $Id: stdio_vfprintf.c,v 1.14 2005-05-07 17:03:55 obarthel Exp $
* $Id: stdio_vfprintf.c,v 1.15 2005-05-08 08:51:29 obarthel Exp $
*
* :ts=4
*
@ -703,7 +703,6 @@ vfprintf(FILE * stream,const char * format, va_list arg)
const char * digit_encoding;
__long_double_t v;
int radix;
int sign;
if(conversion_type == 'a')
{
@ -730,14 +729,14 @@ vfprintf(FILE * stream,const char * format, va_list arg)
else
v = va_arg(arg, double);
if((sign = isinf(v)) != 0)
if(isinf(v))
{
SHOWMSG("infinity");
strcpy(output_buffer,"inf");
output_len = 3;
if(sign < 0)
if(v < 0)
SET_FLAG(format_flags,FORMATF_IsNegative);
fill_character = ' ';
@ -996,13 +995,15 @@ vfprintf(FILE * stream,const char * format, va_list arg)
if(conversion_type == 'e' || conversion_type == 'a')
{
/* For 'long double' the exponent is 15 bits in size, which
allows for a minimum of -16384 to be used. Eight digits
for the exponent should be plenty. */
char exponent_string[8];
char exponent_string[40];
size_t exponent_string_len,j;
int exponent_sign;
/* For the '%a' conversion the exponent is given in
binary notation rather than decimal. */
if(conversion_type == 'a')
radix = 2;
/* Build the exponent string in reverse order. */
exponent_string_len = 0;
@ -1019,9 +1020,9 @@ vfprintf(FILE * stream,const char * format, va_list arg)
while(exponent > 0 && exponent_string_len < sizeof(exponent_string))
{
exponent_string[exponent_string_len++] = '0' + (exponent % 10);
exponent_string[exponent_string_len++] = '0' + (exponent % radix);
exponent /= 10;
exponent /= radix;
}
/* Minimum length of the exponent is two digits. */

View File

@ -1,5 +1,5 @@
/*
* $Id: stdlib_strtod.c,v 1.4 2005-02-27 21:58:21 obarthel Exp $
* $Id: stdlib_strtod.c,v 1.5 2005-05-08 08:51:29 obarthel Exp $
*
* :ts=4
*
@ -67,11 +67,8 @@ double
strtod(const char *str, char ** ptr)
{
double sum = 0.0;
double new_sum;
double result;
int decimal_point_matches;
int is_negative;
int error = 0;
char c;
ENTER();
@ -118,187 +115,250 @@ strtod(const char *str, char ** ptr)
is_negative = 0;
/* But there may be a sign we will choose to
* ignore.
*/
ignore. */
if((*str) == '+')
str++;
}
/* We begin by trying to convert all the digits
* preceding the decimal point.
*/
while((c = (*str)) != '\0')
/* We begin by checking for the "inf" and "nan" strings. */
if(strcasecmp(str,"inf") == SAME || strcasecmp(str,"infinity") == SAME)
{
if('0' <= c && c <= '9')
union ieee_double * x = (union ieee_double *)&sum;
str += strlen(str);
/* Exponent = 2047 and fraction = 0.0 */
x->raw[0] = 0x7ff00000;
x->raw[1] = 0x00000000;
}
else if (strncasecmp(str,"nan",3) == SAME && (str[3] == '(' || str[3] == '\0'))
{
union ieee_double * x = (union ieee_double *)&sum;
str += 3;
/* Does NaN data follow the header? If so, skip it. */
if((*str) == '(')
{
while((*str) != '\0' && (*str) != ')')
str++;
if((*str) == ')')
str++;
}
/* Exponent = 2047 and fraction != 0.0 */
x->raw[0] = 0x7ff00000;
x->raw[1] = 0x00000001;
}
else
{
int decimal_point_matches;
double new_sum;
int error = 0;
int radix;
/* Check for the hex prefix. */
if(strncasecmp(str,"0x",2) == SAME)
{
str += 2;
radix = 16;
}
else
{
radix = 10;
}
/* Convert all the digits preceding the decimal point. */
while((c = (*str)) != '\0')
{
if ('0' <= c && c <= '9')
c = c - '0';
else if ('a' <= c && c <= 'f')
c = c - 'a' + 10;
else if ('A' <= c && c <= 'F')
c = c - 'A' + 10;
else
c = radix;
if(c >= radix)
break;
str++;
if(error == 0)
{
new_sum = (10 * sum) + (c - '0');
new_sum = (radix * sum) + c;
if(new_sum < sum) /* overflow? */
error = ERANGE;
else
sum = new_sum;
}
}
else
/* Did we find the decimal point? We accept both the
locale configured decimal point and the plain old
dot. */
decimal_point_matches = 0;
__locale_lock();
if(__locale_table[LC_NUMERIC] != NULL)
{
break;
}
}
char * point;
/* Did we find the decimal point? We accept both the
* locale configured decimal point and the plain old
* dot.
*/
decimal_point_matches = 0;
__locale_lock();
if(__locale_table[LC_NUMERIC] != NULL)
{
char * point;
point = (char *)__locale_table[LC_NUMERIC]->loc_DecimalPoint;
if((*point) == (*str))
{
decimal_point_matches = 1;
/* Skip the decimal point. */
str++;
}
}
__locale_unlock();
if(NOT decimal_point_matches)
{
if((*str) == '.')
{
decimal_point_matches = 1;
/* Skip the decimal point. */
str++;
}
}
if(decimal_point_matches)
{
double divisor = 0.1;
/* Process all digits following the decimal point. */
while((c = (*str)) != '\0')
{
if('0' <= c && c <= '9')
point = (char *)__locale_table[LC_NUMERIC]->loc_DecimalPoint;
if((*point) == (*str))
{
decimal_point_matches = 1;
/* Skip the decimal point. */
str++;
}
}
__locale_unlock();
if(NOT decimal_point_matches)
{
if((*str) == '.')
{
decimal_point_matches = 1;
/* Skip the decimal point. */
str++;
}
}
if(decimal_point_matches)
{
double divisor = 1.0 / radix;
/* Process all digits following the decimal point. */
while((c = (*str)) != '\0')
{
if ('0' <= c && c <= '9')
c = c - '0';
else if ('a' <= c && c <= 'f')
c = c - 'a' + 10;
else if ('A' <= c && c <= 'F')
c = c - 'A' + 10;
else
c = radix;
if(c >= radix)
break;
str++;
if(error == 0 && divisor != 0.0)
{
new_sum = sum + (c - '0') * divisor;
new_sum = sum + c * divisor;
if(new_sum < sum) /* overflow? */
error = ERANGE;
else
sum = new_sum;
divisor = divisor / 10.0;
divisor = divisor / radix;
}
}
}
/* If there is a scale indicator attached, process it. */
if((radix == 10 && ((*str) == 'e' || (*str) == 'E')) ||
(radix == 16 && ((*str) == 'p' || (*str) == 'P')))
{
int exponent_is_negative;
int new_exponent;
int exponent = 0;
/* If we are processing a hexadecimal encoded
floating point number, switch to a binary
exponent. */
if(radix == 16)
radix = 2;
/* Skip the indicator. */
str++;
/* Take care of the exponent's sign. */
if((*str) == '-')
{
exponent_is_negative = 1;
str++;
}
else
{
break;
exponent_is_negative = 0;
if((*str) == '+')
str++;
}
}
}
/* If there is a scale indicator attached, process it. */
if((*str) == 'e' || (*str) == 'E')
{
int exponent_is_negative;
int new_exponent;
int exponent = 0;
/* Skip the indicator. */
str++;
/* Take care of the exponent's sign. */
if((*str) == '-')
{
exponent_is_negative = 1;
str++;
}
else
{
exponent_is_negative = 0;
if((*str) == '+')
str++;
}
/* Again, process all digits to follow. */
while((c = (*str)) != '\0')
{
if('0' <= c && c <= '9')
/* Again, process all digits to follow. */
while((c = (*str)) != '\0')
{
if('0' <= c && c <= '9')
c -= '0';
else
c = radix;
if(c >= radix)
break;
str++;
if(error == 0)
{
new_exponent = (10 * exponent) + (c - '0');
new_exponent = (radix * exponent) + c;
if(new_exponent < exponent) /* overflow? */
error = ERANGE;
else
exponent = new_exponent;
}
}
else
{
break;
}
}
/* If the exponent is valid, scale the number
* accordingly.
*/
if(exponent != 0)
{
if(exponent_is_negative)
/* If the exponent is valid, scale the number accordingly. */
if(exponent != 0)
{
double divisor;
/* A negative exponent means division. */
divisor = pow(10.0,(double)exponent);
if(divisor != 0.0)
if(exponent_is_negative)
{
new_sum = sum / divisor;
if(new_sum == 0.0 && sum != 0.0)
double divisor;
/* A negative exponent means division. */
divisor = pow(radix,(double)exponent);
if(divisor != 0.0)
{
new_sum = sum / divisor;
if(new_sum == 0.0 && sum != 0.0)
error = ERANGE;
else
sum = new_sum;
}
else
{
error = ERANGE;
}
}
else
{
/* A positive exponent means multiplication. */
new_sum = sum * pow(radix,(double)exponent);
if(new_sum < sum)
error = ERANGE;
else
sum = new_sum;
}
else
{
error = ERANGE;
}
}
else
{
/* A positive exponent means multiplication. */
new_sum = sum * pow(10.0,(double)exponent);
if(new_sum < sum)
error = ERANGE;
else
sum = new_sum;
}
}
}
if(error != 0)
{
__set_errno(error);
if(error != 0)
{
__set_errno(error);
sum = __get_huge_val();
sum = __get_huge_val();
}
}
if(is_negative)
@ -307,8 +367,7 @@ strtod(const char *str, char ** ptr)
result = sum;
/* If desired, remember where we stopped reading the
* number from the buffer.
*/
number from the buffer. */
if(ptr != NULL)
(*ptr) = (char *)str;

View File

@ -1,5 +1,5 @@
/*
* $Id: stdlib_strtof.c,v 1.2 2005-05-07 17:03:55 obarthel Exp $
* $Id: stdlib_strtof.c,v 1.3 2005-05-08 08:51:29 obarthel Exp $
*
* :ts=4
*
@ -67,11 +67,8 @@ float
strtof(const char *str, char ** ptr)
{
float sum = 0.0;
float new_sum;
float result;
int decimal_point_matches;
int is_negative;
int error = 0;
char c;
ENTER();
@ -118,187 +115,248 @@ strtof(const char *str, char ** ptr)
is_negative = 0;
/* But there may be a sign we will choose to
* ignore.
*/
ignore. */
if((*str) == '+')
str++;
}
/* We begin by trying to convert all the digits
* preceding the decimal point.
*/
while((c = (*str)) != '\0')
/* We begin by checking for the "inf" and "nan" strings. */
if(strcasecmp(str,"inf") == SAME || strcasecmp(str,"infinity") == SAME)
{
if('0' <= c && c <= '9')
union ieee_single * x = (union ieee_single *)&sum;
str += strlen(str);
/* Exponent = 255 and fraction = 0.0 */
x->raw[0] = 0x7f800000;
}
else if (strncasecmp(str,"nan",3) == SAME && (str[3] == '(' || str[3] == '\0'))
{
union ieee_single * x = (union ieee_single *)&sum;
str += 3;
/* Does NaN data follow the header? If so, skip it. */
if((*str) == '(')
{
while((*str) != '\0' && (*str) != ')')
str++;
if((*str) == ')')
str++;
}
/* Exponent = 255 and fraction != 0.0 */
x->raw[0] = 0x7f800001;
}
else
{
int decimal_point_matches;
float new_sum;
int error = 0;
int radix;
/* Check for the hex prefix. */
if(strncasecmp(str,"0x",2) == SAME)
{
str += 2;
radix = 16;
}
else
{
radix = 10;
}
/* Convert all the digits preceding the decimal point. */
while((c = (*str)) != '\0')
{
if ('0' <= c && c <= '9')
c = c - '0';
else if ('a' <= c && c <= 'f')
c = c - 'a' + 10;
else if ('A' <= c && c <= 'F')
c = c - 'A' + 10;
else
c = radix;
if(c >= radix)
break;
str++;
if(error == 0)
{
new_sum = (10 * sum) + (c - '0');
new_sum = (radix * sum) + c;
if(new_sum < sum) /* overflow? */
error = ERANGE;
else
sum = new_sum;
}
}
else
/* Did we find the decimal point? We accept both the
locale configured decimal point and the plain old
dot. */
decimal_point_matches = 0;
__locale_lock();
if(__locale_table[LC_NUMERIC] != NULL)
{
break;
}
}
char * point;
/* Did we find the decimal point? We accept both the
* locale configured decimal point and the plain old
* dot.
*/
decimal_point_matches = 0;
__locale_lock();
if(__locale_table[LC_NUMERIC] != NULL)
{
char * point;
point = (char *)__locale_table[LC_NUMERIC]->loc_DecimalPoint;
if((*point) == (*str))
{
decimal_point_matches = 1;
/* Skip the decimal point. */
str++;
}
}
__locale_unlock();
if(NOT decimal_point_matches)
{
if((*str) == '.')
{
decimal_point_matches = 1;
/* Skip the decimal point. */
str++;
}
}
if(decimal_point_matches)
{
float divisor = 0.1;
/* Process all digits following the decimal point. */
while((c = (*str)) != '\0')
{
if('0' <= c && c <= '9')
point = (char *)__locale_table[LC_NUMERIC]->loc_DecimalPoint;
if((*point) == (*str))
{
decimal_point_matches = 1;
/* Skip the decimal point. */
str++;
}
}
__locale_unlock();
if(NOT decimal_point_matches)
{
if((*str) == '.')
{
decimal_point_matches = 1;
/* Skip the decimal point. */
str++;
}
}
if(decimal_point_matches)
{
float divisor = 1.0 / radix;
/* Process all digits following the decimal point. */
while((c = (*str)) != '\0')
{
if ('0' <= c && c <= '9')
c = c - '0';
else if ('a' <= c && c <= 'f')
c = c - 'a' + 10;
else if ('A' <= c && c <= 'F')
c = c - 'A' + 10;
else
c = radix;
if(c >= radix)
break;
str++;
if(error == 0 && divisor != 0.0)
{
new_sum = sum + (c - '0') * divisor;
new_sum = sum + c * divisor;
if(new_sum < sum) /* overflow? */
error = ERANGE;
else
sum = new_sum;
divisor = divisor / 10.0;
divisor = divisor / radix;
}
}
}
/* If there is a scale indicator attached, process it. */
if((radix == 10 && ((*str) == 'e' || (*str) == 'E')) ||
(radix == 16 && ((*str) == 'p' || (*str) == 'P')))
{
int exponent_is_negative;
int new_exponent;
int exponent = 0;
/* If we are processing a hexadecimal encoded
floating point number, switch to a binary
exponent. */
if(radix == 16)
radix = 2;
/* Skip the indicator. */
str++;
/* Take care of the exponent's sign. */
if((*str) == '-')
{
exponent_is_negative = 1;
str++;
}
else
{
break;
exponent_is_negative = 0;
if((*str) == '+')
str++;
}
}
}
/* If there is a scale indicator attached, process it. */
if((*str) == 'e' || (*str) == 'E')
{
int exponent_is_negative;
int new_exponent;
int exponent = 0;
/* Skip the indicator. */
str++;
/* Take care of the exponent's sign. */
if((*str) == '-')
{
exponent_is_negative = 1;
str++;
}
else
{
exponent_is_negative = 0;
if((*str) == '+')
str++;
}
/* Again, process all digits to follow. */
while((c = (*str)) != '\0')
{
if('0' <= c && c <= '9')
/* Again, process all digits to follow. */
while((c = (*str)) != '\0')
{
if('0' <= c && c <= '9')
c -= '0';
else
c = radix;
if(c >= radix)
break;
str++;
if(error == 0)
{
new_exponent = (10 * exponent) + (c - '0');
new_exponent = (radix * exponent) + c;
if(new_exponent < exponent) /* overflow? */
error = ERANGE;
else
exponent = new_exponent;
}
}
else
{
break;
}
}
/* If the exponent is valid, scale the number
* accordingly.
*/
if(exponent != 0)
{
if(exponent_is_negative)
/* If the exponent is valid, scale the number accordingly. */
if(exponent != 0)
{
float divisor;
/* A negative exponent means division. */
divisor = pow(10.0,(float)exponent);
if(divisor != 0.0)
if(exponent_is_negative)
{
new_sum = sum / divisor;
if(new_sum == 0.0 && sum != 0.0)
float divisor;
/* A negative exponent means division. */
divisor = pow(radix,(float)exponent);
if(divisor != 0.0)
{
new_sum = sum / divisor;
if(new_sum == 0.0 && sum != 0.0)
error = ERANGE;
else
sum = new_sum;
}
else
{
error = ERANGE;
}
}
else
{
/* A positive exponent means multiplication. */
new_sum = sum * pow(radix,(float)exponent);
if(new_sum < sum)
error = ERANGE;
else
sum = new_sum;
}
else
{
error = ERANGE;
}
}
else
{
/* A positive exponent means multiplication. */
new_sum = sum * pow(10.0,(float)exponent);
if(new_sum < sum)
error = ERANGE;
else
sum = new_sum;
}
}
}
if(error != 0)
{
__set_errno(error);
if(error != 0)
{
__set_errno(error);
sum = __get_huge_valf();
sum = __get_huge_valf();
}
}
if(is_negative)
@ -307,8 +365,7 @@ strtof(const char *str, char ** ptr)
result = sum;
/* If desired, remember where we stopped reading the
* number from the buffer.
*/
number from the buffer. */
if(ptr != NULL)
(*ptr) = (char *)str;