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:
@ -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 \
|
||||
|
||||
@ -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 \
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -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
142
library/math_fabsf.c
Normal 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
97
library/math_fpclassify.c
Normal 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
89
library/math_isfinite.c
Normal 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 */
|
||||
@ -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
63
library/math_nan.c
Normal 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
62
library/math_nanf.c
Normal 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
79
library/math_signbit.c
Normal 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 */
|
||||
@ -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 \
|
||||
|
||||
@ -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. */
|
||||
|
||||
@ -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 *)∑
|
||||
|
||||
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 *)∑
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@ -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 *)∑
|
||||
|
||||
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 *)∑
|
||||
|
||||
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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user