diff options
author | Otto Moerbeek <otto@cvs.openbsd.org> | 2005-11-17 20:07:41 +0000 |
---|---|---|
committer | Otto Moerbeek <otto@cvs.openbsd.org> | 2005-11-17 20:07:41 +0000 |
commit | 634b9611f69bc903d28767f9136ac135bb18062d (patch) | |
tree | 3f22afb6f647b922a47bd673818b581e63914f32 | |
parent | b576ee6329bd9a75c52d43af23ef0809e1eecf12 (diff) |
Introduce a few c99 functions: {l,ll}{rint,round}{,f}. From NetBSD via
jason@. Man page fixes by jmc@, prodding by jsg@. ok mickey@
-rw-r--r-- | include/math.h | 10 | ||||
-rw-r--r-- | lib/libm/Makefile | 15 | ||||
-rw-r--r-- | lib/libm/man/lrint.3 | 101 | ||||
-rw-r--r-- | lib/libm/man/lround.3 | 100 | ||||
-rw-r--r-- | lib/libm/shlib_version | 2 | ||||
-rw-r--r-- | lib/libm/src/llrint.c | 14 | ||||
-rw-r--r-- | lib/libm/src/llrintf.c | 14 | ||||
-rw-r--r-- | lib/libm/src/llround.c | 14 | ||||
-rw-r--r-- | lib/libm/src/llroundf.c | 14 | ||||
-rw-r--r-- | lib/libm/src/lrint.c | 95 | ||||
-rw-r--r-- | lib/libm/src/lrintf.c | 90 | ||||
-rw-r--r-- | lib/libm/src/lround.c | 88 | ||||
-rw-r--r-- | lib/libm/src/lroundf.c | 83 |
13 files changed, 634 insertions, 6 deletions
diff --git a/include/math.h b/include/math.h index 964dde4e674..77d59695876 100644 --- a/include/math.h +++ b/include/math.h @@ -1,4 +1,4 @@ -/* $OpenBSD: math.h,v 1.9 2005/01/06 20:36:23 espie Exp $ */ +/* $OpenBSD: math.h,v 1.10 2005/11/17 20:07:40 otto Exp $ */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. @@ -182,6 +182,10 @@ extern double significand(double); extern double copysign(double, double); extern int ilogb(double); extern double rint(double); +extern long int lrint(double); +extern long int lround(double); +extern long long int llrint(double); +extern long long int llround(double); extern double scalbn(double, int); /* @@ -266,6 +270,10 @@ extern float significandf(float); extern float copysignf(float, float); extern int ilogbf(float); extern float rintf(float); +extern long int lrintf(float); +extern long int lroundf(float); +extern long long int llrintf(float); +extern long long int llroundf(float); extern float scalbnf(float, int); /* diff --git a/lib/libm/Makefile b/lib/libm/Makefile index ecd161b5e1c..aa7debe6277 100644 --- a/lib/libm/Makefile +++ b/lib/libm/Makefile @@ -1,5 +1,5 @@ # $NetBSD: Makefile,v 1.28 1995/11/20 22:06:19 jtc Exp $ -# $OpenBSD: Makefile,v 1.34 2004/04/06 00:21:18 brad Exp $ +# $OpenBSD: Makefile,v 1.35 2005/11/17 20:07:40 otto Exp $ # # @(#)Makefile 5.1beta 93/09/24 # @@ -107,6 +107,8 @@ COMMON_SRCS = e_acos.c e_acosf.c e_acosh.c e_acoshf.c e_asin.c e_asinf.c \ e_sinh.c e_sinhf.c e_sqrt.c e_sqrtf.c \ k_cos.c k_cosf.c k_rem_pio2.c k_rem_pio2f.c k_sin.c k_sinf.c \ k_standard.c k_tan.c k_tanf.c \ + lrint.c lrintf.c llrint.c llrintf.c lround.c lroundf.c llround.c \ + llroundf.c \ s_asinh.c s_asinhf.c s_atan.c s_atanf.c s_cbrt.c s_cbrtf.c s_ceil.c \ s_ceilf.c s_copysign.c s_copysignf.c s_cos.c s_cosf.c s_erf.c s_erff.c \ s_expm1.c s_expm1f.c s_fabsf.c s_finite.c s_finitef.c \ @@ -157,9 +159,8 @@ SRCS= ${COMMON_SRCS} MAN+= acos.3 acosh.3 asin.3 asinh.3 atan.3 atan2.3 atanh.3 ceil.3 \ cos.3 cosh.3 erf.3 exp.3 fabs.3 floor.3 fmod.3 hypot.3 ieee.3 \ - logb.3 j0.3 lgamma.3 math.3 rint.3 sin.3 sinh.3 sqrt.3 \ - tan.3 tanh.3 -MAN+= infnan.3 + infnan.3 logb.3 j0.3 lgamma.3 lrint.3 lround.3 math.3 rint.3 \ + sin.3 sinh.3 sqrt.3 tan.3 tanh.3 MLINKS+=erf.3 erfc.3 MLINKS+=exp.3 expm1.3 exp.3 log.3 exp.3 log10.3 exp.3 log1p.3 exp.3 pow.3 @@ -214,6 +215,12 @@ MLINKS+=j0.3 y1f.3 MLINKS+=j0.3 ynf.3 MLINKS+=lgamma.3 gammaf.3 MLINKS+=lgamma.3 lgammaf.3 +MLINKS+=lrint.3 lrintf.3 +MLINKS+=lrint.3 llrint.3 +MLINKS+=lrint.3 llrintf.3 +MLINKS+=lround.3 lroundf.3 +MLINKS+=lround.3 llround.3 +MLINKS+=lround.3 llroundf.3 MLINKS+=math.3 mathf.3 MLINKS+=rint.3 rintf.3 MLINKS+=sin.3 sinf.3 diff --git a/lib/libm/man/lrint.3 b/lib/libm/man/lrint.3 new file mode 100644 index 00000000000..e4a35609fe7 --- /dev/null +++ b/lib/libm/man/lrint.3 @@ -0,0 +1,101 @@ +.\" $OpenBSD: lrint.3,v 1.1 2005/11/17 20:07:40 otto Exp $ +.\" $NetBSD: lrint.3,v 1.1 2005/09/16 15:26:47 wiz Exp $ +.\" +.\" Copyright (c) 2005 David Schultz <das@FreeBSD.org> +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: /repoman/r/ncvs/src/lib/msun/man/lrint.3,v 1.2.2.2 2005/03/01 16:18:39 brueffer Exp $ +.\" +.Dd January 11, 2005 +.Dt LRINT 3 +.Os +.Sh NAME +.Nm llrint , +.Nm llrintf , +.Nm lrint , +.Nm lrintf +.Nd convert to integer +.Sh SYNOPSIS +.In math.h +.Ft long long +.Fn llrint "double x" +.Ft long long +.Fn llrintf "float x" +.Ft long +.Fn lrint "double x" +.Ft long +.Fn lrintf "float x" +.Sh DESCRIPTION +The +.Fn lrint +function returns the integer nearest to its argument +.Fa x +according to the current rounding mode. +.Pp +The +.Fn llrint , +.Fn llrintf , +and +.Fn lrintf +functions differ from +.Fn lrint +only in their input and output types. +.Sh RETURN VALUES +The +.Nm llrint , +.Nm llrintf , +.Nm lrint , +and +.Nm lrintf +functions return the integer nearest to their argument +.Fa x +according to the current rounding mode. +If the rounded result is too large to be represented as a +.Vt long long +or +.Vt long +value, respectively, +.\" an invalid exception is raised and +the return value is undefined. +.\" Otherwise, if +.\" .Fa x +.\" is not an integer, +.\" .Fn lrint +.\" raises an inexact exception. +.\" If +.\" .Fa x +.\" is too large, a range error may occur. +.Sh SEE ALSO +.Xr lround 3 , +.Xr math 3 , +.Xr rint 3 +.Sh STANDARDS +The +.Fn llrint , +.Fn llrintf , +.Fn lrint , +and +.Fn lrintf +functions conform to +.St -isoC-99 . diff --git a/lib/libm/man/lround.3 b/lib/libm/man/lround.3 new file mode 100644 index 00000000000..42dc24e472b --- /dev/null +++ b/lib/libm/man/lround.3 @@ -0,0 +1,100 @@ +.\" $OpenBSD: lround.3,v 1.1 2005/11/17 20:07:40 otto Exp $ +.\" +.\" Copyright (c) 2005 David Schultz <das@FreeBSD.org> +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: /repoman/r/ncvs/src/lib/msun/man/lround.3,v 1.4 2005/06/15 19:04:04 ru Exp $ +.\" +.Dd April 7, 2005 +.Dt LROUND 3 +.Os +.Sh NAME +.Nm llround , +.Nm llroundf , +.\" .Nm llroundl , +.Nm lround , +.Nm lroundf +.\" .Nm lroundl +.Nd "convert to nearest integral value" +.Sh SYNOPSIS +.In math.h +.Ft "long long" +.Fn llround "double x" +.Ft "long long" +.Fn llroundf "float x" +.\" .Ft "long long" +.\" .Fn llroundl "long double x" +.Ft long +.Fn lround "double x" +.Ft long +.Fn lroundf "float x" +.\" .Ft long +.\" .Fn lroundl "long double x" +.Sh DESCRIPTION +The +.Fn lround +function returns the integer nearest to its argument +.Fa x , +rounding away from zero in halfway cases. +If the rounded result is too large to be represented as a +.Vt long +value, an invalid exception is raised and the return value is undefined. +Otherwise, if +.Fa x +is not an integer, +.Fn lround +may raise an inexact exception. +When the rounded result is representable as a +.Vt long , +the expression +.Fn lround x +is equivalent to +.Po Vt long Pc Ns Fn round x +(although the former may be more efficient). +.Pp +The +.Fn llround , +.Fn llroundf , +.\" .Fn llroundl , +.\" .Fn lroundl +and +.Fn lroundf +functions differ from +.Fn lround +only in their input and output types. +.Sh SEE ALSO +.Xr lrint 3 , +.Xr math 3 , +.Xr rint 3 +.Sh STANDARDS +The +.Fn llround , +.Fn llroundf , +.\" .Fn lroundl +.\" .Fn llroundl , +.Fn lround , +and +.Fn lroundf +functions conform to +.St -isoC-99 . diff --git a/lib/libm/shlib_version b/lib/libm/shlib_version index b52599a164f..c6e3f4d3fc0 100644 --- a/lib/libm/shlib_version +++ b/lib/libm/shlib_version @@ -1,2 +1,2 @@ major=2 -minor=0 +minor=1 diff --git a/lib/libm/src/llrint.c b/lib/libm/src/llrint.c new file mode 100644 index 00000000000..c92da9e3c7d --- /dev/null +++ b/lib/libm/src/llrint.c @@ -0,0 +1,14 @@ +/* $OpenBSD: llrint.c,v 1.1 2005/11/17 20:07:40 otto Exp $ */ +/* $NetBSD: llrint.c,v 1.2 2004/10/13 15:18:32 drochner Exp $ */ + +/* + * Written by Matthias Drochner <drochner@NetBSD.org>. + * Public domain. + */ + +#define LRINTNAME llrint +#define RESTYPE long long int +#define RESTYPE_MIN LLONG_MIN +#define RESTYPE_MAX LLONG_MAX + +#include "lrint.c" diff --git a/lib/libm/src/llrintf.c b/lib/libm/src/llrintf.c new file mode 100644 index 00000000000..2a242afb13d --- /dev/null +++ b/lib/libm/src/llrintf.c @@ -0,0 +1,14 @@ +/* $OpenBSD: llrintf.c,v 1.1 2005/11/17 20:07:40 otto Exp $ */ +/* $NetBSD: llrintf.c,v 1.2 2004/10/13 15:18:32 drochner Exp $ */ + +/* + * Written by Matthias Drochner <drochner@NetBSD.org>. + * Public domain. + */ + +#define LRINTNAME llrintf +#define RESTYPE long long int +#define RESTYPE_MIN LLONG_MIN +#define RESTYPE_MAX LLONG_MAX + +#include "lrintf.c" diff --git a/lib/libm/src/llround.c b/lib/libm/src/llround.c new file mode 100644 index 00000000000..b52c02c3291 --- /dev/null +++ b/lib/libm/src/llround.c @@ -0,0 +1,14 @@ +/* $OpenBSD: llround.c,v 1.1 2005/11/17 20:07:40 otto Exp $ */ +/* $NetBSD: llround.c,v 1.2 2004/10/13 15:18:32 drochner Exp $ */ + +/* + * Written by Matthias Drochner <drochner@NetBSD.org>. + * Public domain. + */ + +#define LROUNDNAME llround +#define RESTYPE long long int +#define RESTYPE_MIN LLONG_MIN +#define RESTYPE_MAX LLONG_MAX + +#include "lround.c" diff --git a/lib/libm/src/llroundf.c b/lib/libm/src/llroundf.c new file mode 100644 index 00000000000..24ab53cd813 --- /dev/null +++ b/lib/libm/src/llroundf.c @@ -0,0 +1,14 @@ +/* $OpenBSD: llroundf.c,v 1.1 2005/11/17 20:07:40 otto Exp $ */ +/* $NetBSD: llroundf.c,v 1.2 2004/10/13 15:18:32 drochner Exp $ */ + +/* + * Written by Matthias Drochner <drochner@NetBSD.org>. + * Public domain. + */ + +#define LROUNDNAME llroundf +#define RESTYPE long long int +#define RESTYPE_MIN LLONG_MIN +#define RESTYPE_MAX LLONG_MAX + +#include "lroundf.c" diff --git a/lib/libm/src/lrint.c b/lib/libm/src/lrint.c new file mode 100644 index 00000000000..146bc81b10f --- /dev/null +++ b/lib/libm/src/lrint.c @@ -0,0 +1,95 @@ +/* $OpenBSD: lrint.c,v 1.1 2005/11/17 20:07:40 otto Exp $ */ +/* $NetBSD: lrint.c,v 1.3 2004/10/13 15:18:32 drochner Exp $ */ + +/*- + * Copyright (c) 2004 + * Matthias Drochner. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include <sys/types.h> +#include <sys/limits.h> +#include <math.h> +#include <ieeefp.h> +#include <machine/ieee.h> +#include "math_private.h" + +#ifndef LRINTNAME +#define LRINTNAME lrint +#define RESTYPE long int +#define RESTYPE_MIN LONG_MIN +#define RESTYPE_MAX LONG_MAX +#endif + +#define RESTYPE_BITS (sizeof(RESTYPE) * 8) + +static const double +TWO52[2]={ + 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ + -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ +}; + +RESTYPE +LRINTNAME(double x) +{ + u_int32_t i0, i1; + int e, s, shift; + RESTYPE res; + + GET_HIGH_WORD(i0, x); + e = i0 >> 20; + s = e >> DBL_EXPBITS; + e = (e & 0x7ff) - DBL_EXP_BIAS; + + /* 1.0 x 2^-1 is the smallest number which can be rounded to 1 */ + if (e < -1) + return (0); + /* 1.0 x 2^31 (or 2^63) is already too large */ + if (e >= (int)RESTYPE_BITS - 1) + return (s ? RESTYPE_MIN : RESTYPE_MAX); /* ??? unspecified */ + + /* >= 2^52 is already an exact integer */ + if (e < DBL_FRACBITS) { + /* round, using current direction */ + x += TWO52[s]; + x -= TWO52[s]; + } + + EXTRACT_WORDS(i0, i1, x); + e = ((i0 >> 20) & 0x7ff) - DBL_EXP_BIAS; + i0 &= 0xfffff; + i0 |= (1 << 20); + + shift = e - DBL_FRACBITS; + if (shift >=0) + res = (shift < 32 ? (RESTYPE)i1 << shift : 0); + else + res = (shift > -32 ? i1 >> -shift : 0); + shift += 32; + if (shift >=0) + res |= (shift < 32 ? (RESTYPE)i0 << shift : 0); + else + res |= (shift > -32 ? i0 >> -shift : 0); + + return (s ? -res : res); +} diff --git a/lib/libm/src/lrintf.c b/lib/libm/src/lrintf.c new file mode 100644 index 00000000000..18027152ba4 --- /dev/null +++ b/lib/libm/src/lrintf.c @@ -0,0 +1,90 @@ +/* $OpenBSD: lrintf.c,v 1.1 2005/11/17 20:07:40 otto Exp $ */ +/* $NetBSD: lrintf.c,v 1.3 2004/10/13 15:18:32 drochner Exp $ */ + +/*- + * Copyright (c) 2004 + * Matthias Drochner. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include <sys/types.h> +#include <sys/limits.h> +#include <math.h> +#include <ieeefp.h> +#include <machine/ieee.h> +#include "math_private.h" + +#ifndef LRINTNAME +#define LRINTNAME lrintf +#define RESTYPE long int +#define RESTYPE_MIN LONG_MIN +#define RESTYPE_MAX LONG_MAX +#endif + +#define RESTYPE_BITS (sizeof(RESTYPE) * 8) + +static const float +TWO23[2]={ + 8.3886080000e+06, /* 0x4b000000 */ + -8.3886080000e+06, /* 0xcb000000 */ +}; + +RESTYPE +LRINTNAME(float x) +{ + u_int32_t i0; + int e, s, shift; + RESTYPE res; + + GET_FLOAT_WORD(i0, x); + e = i0 >> SNG_FRACBITS; + s = e >> SNG_EXPBITS; + e = (e & 0xff) - SNG_EXP_BIAS; + + /* 1.0 x 2^-1 is the smallest number which can be rounded to 1 */ + if (e < -1) + return (0); + /* 1.0 x 2^31 (or 2^63) is already too large */ + if (e >= (int)RESTYPE_BITS - 1) + return (s ? RESTYPE_MIN : RESTYPE_MAX); /* ??? unspecified */ + + /* >= 2^23 is already an exact integer */ + if (e < SNG_FRACBITS) { + /* round, using current direction */ + x += TWO23[s]; + x -= TWO23[s]; + } + + GET_FLOAT_WORD(i0, x); + e = ((i0 >> SNG_FRACBITS) & 0xff) - SNG_EXP_BIAS; + i0 &= 0x7fffff; + i0 |= (1 << SNG_FRACBITS); + + shift = e - SNG_FRACBITS; + if (shift >=0) + res = (shift < 32 ? (RESTYPE)i0 << shift : 0); + else + res = (shift > -32 ? i0 >> -shift : 0); + + return (s ? -res : res); +} diff --git a/lib/libm/src/lround.c b/lib/libm/src/lround.c new file mode 100644 index 00000000000..62fbe3ebea3 --- /dev/null +++ b/lib/libm/src/lround.c @@ -0,0 +1,88 @@ +/* $OpenBSD: lround.c,v 1.1 2005/11/17 20:07:40 otto Exp $ */ +/* $NetBSD: lround.c,v 1.2 2004/10/13 15:18:32 drochner Exp $ */ + +/*- + * Copyright (c) 2004 + * Matthias Drochner. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include <sys/types.h> +#include <sys/limits.h> +#include <math.h> +#include <ieeefp.h> +#include <machine/ieee.h> +#include "math_private.h" + +#ifndef LROUNDNAME +#define LROUNDNAME lround +#define RESTYPE long int +#define RESTYPE_MIN LONG_MIN +#define RESTYPE_MAX LONG_MAX +#endif + +#define RESTYPE_BITS (sizeof(RESTYPE) * 8) + +RESTYPE +LROUNDNAME(double x) +{ + u_int32_t i0, i1; + int e, s, shift; + RESTYPE res; + + GET_HIGH_WORD(i0, x); + e = i0 >> 20; + s = e >> DBL_EXPBITS; + e = (e & 0x7ff) - DBL_EXP_BIAS; + + /* 1.0 x 2^-1 is the smallest number which can be rounded to 1 */ + if (e < -1) + return (0); + /* 1.0 x 2^31 (or 2^63) is already too large */ + if (e >= (int)RESTYPE_BITS - 1) + return (s ? RESTYPE_MIN : RESTYPE_MAX); /* ??? unspecified */ + + /* >= 2^52 is already an exact integer */ + if (e < DBL_FRACBITS) { + /* add 0.5, extraction below will truncate */ + x += (s ? -0.5 : 0.5); + } + + EXTRACT_WORDS(i0, i1, x); + e = ((i0 >> 20) & 0x7ff) - DBL_EXP_BIAS; + i0 &= 0xfffff; + i0 |= (1 << 20); + + shift = e - DBL_FRACBITS; + if (shift >=0) + res = (shift < 32 ? (RESTYPE)i1 << shift : 0); + else + res = (shift > -32 ? i1 >> -shift : 0); + shift += 32; + if (shift >=0) + res |= (shift < 32 ? (RESTYPE)i0 << shift : 0); + else + res |= (shift > -32 ? i0 >> -shift : 0); + + return (s ? -res : res); +} diff --git a/lib/libm/src/lroundf.c b/lib/libm/src/lroundf.c new file mode 100644 index 00000000000..477383d81bd --- /dev/null +++ b/lib/libm/src/lroundf.c @@ -0,0 +1,83 @@ +/* $OpenBSD: lroundf.c,v 1.1 2005/11/17 20:07:40 otto Exp $ */ +/* $NetBSD: lroundf.c,v 1.2 2004/10/13 15:18:32 drochner Exp $ */ + +/*- + * Copyright (c) 2004 + * Matthias Drochner. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include <math.h> +#include <sys/types.h> +#include <sys/limits.h> +#include <ieeefp.h> +#include <machine/ieee.h> +#include "math_private.h" + +#ifndef LROUNDNAME +#define LROUNDNAME lroundf +#define RESTYPE long int +#define RESTYPE_MIN LONG_MIN +#define RESTYPE_MAX LONG_MAX +#endif + +#define RESTYPE_BITS (sizeof(RESTYPE) * 8) + +RESTYPE +LROUNDNAME(float x) +{ + u_int32_t i0; + int e, s, shift; + RESTYPE res; + + GET_FLOAT_WORD(i0, x); + e = i0 >> SNG_FRACBITS; + s = e >> SNG_EXPBITS; + e = (e & 0xff) - SNG_EXP_BIAS; + + /* 1.0 x 2^-1 is the smallest number which can be rounded to 1 */ + if (e < -1) + return (0); + /* 1.0 x 2^31 (or 2^63) is already too large */ + if (e >= (int)RESTYPE_BITS - 1) + return (s ? RESTYPE_MIN : RESTYPE_MAX); /* ??? unspecified */ + + /* >= 2^23 is already an exact integer */ + if (e < SNG_FRACBITS) { + /* add 0.5, extraction below will truncate */ + x += (s ? -0.5 : 0.5); + } + + GET_FLOAT_WORD(i0, x); + e = ((i0 >> SNG_FRACBITS) & 0xff) - SNG_EXP_BIAS; + i0 &= 0x7fffff; + i0 |= (1 << SNG_FRACBITS); + + shift = e - SNG_FRACBITS; + if (shift >=0) + res = (shift < 32 ? (RESTYPE)i0 << shift : 0); + else + res = (shift > -32 ? i0 >> -shift : 0); + + return (s ? -res : res); +} |