* commit 'cf2c663937b440ce78a195262a7f2d3d5b9a7157': Reimplement isinf/isnan/fpclassify.
This commit is contained in:
commit
9f3011ff59
@ -60,3 +60,112 @@ static void BM_math_logb(int iters) {
|
||||
StopBenchmarkTiming();
|
||||
}
|
||||
BENCHMARK(BM_math_logb);
|
||||
|
||||
static void BM_math_isinf_NORMAL(int iters) {
|
||||
StartBenchmarkTiming();
|
||||
|
||||
d = 0.0;
|
||||
v = 1234.0; // FP_NORMAL
|
||||
for (int i = 0; i < iters; ++i) {
|
||||
d += (isinf)(v);
|
||||
}
|
||||
|
||||
StopBenchmarkTiming();
|
||||
}
|
||||
BENCHMARK(BM_math_isinf_NORMAL);
|
||||
|
||||
static void BM_math_isinf_NAN(int iters) {
|
||||
StartBenchmarkTiming();
|
||||
|
||||
d = 0.0;
|
||||
v = nan(""); // FP_NAN
|
||||
for (int i = 0; i < iters; ++i) {
|
||||
d += (isinf)(v);
|
||||
}
|
||||
|
||||
StopBenchmarkTiming();
|
||||
}
|
||||
BENCHMARK(BM_math_isinf_NAN);
|
||||
|
||||
static void BM_math_isinf_INFINITE(int iters) {
|
||||
StartBenchmarkTiming();
|
||||
|
||||
d = 0.0;
|
||||
v = HUGE_VAL; // FP_INFINITE
|
||||
for (int i = 0; i < iters; ++i) {
|
||||
d += (isinf)(v);
|
||||
}
|
||||
|
||||
StopBenchmarkTiming();
|
||||
}
|
||||
BENCHMARK(BM_math_isinf_INFINITE);
|
||||
|
||||
static void BM_math_isinf_ZERO(int iters) {
|
||||
StartBenchmarkTiming();
|
||||
|
||||
d = 0.0;
|
||||
v = 0.0; // FP_ZERO
|
||||
for (int i = 0; i < iters; ++i) {
|
||||
d += (isinf)(v);
|
||||
}
|
||||
|
||||
StopBenchmarkTiming();
|
||||
}
|
||||
BENCHMARK(BM_math_isinf_ZERO);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void BM_math_fpclassify_NORMAL(int iters) {
|
||||
StartBenchmarkTiming();
|
||||
|
||||
d = 0.0;
|
||||
v = 1234.0; // FP_NORMAL
|
||||
for (int i = 0; i < iters; ++i) {
|
||||
d += fpclassify(v);
|
||||
}
|
||||
|
||||
StopBenchmarkTiming();
|
||||
}
|
||||
BENCHMARK(BM_math_fpclassify_NORMAL);
|
||||
|
||||
static void BM_math_fpclassify_NAN(int iters) {
|
||||
StartBenchmarkTiming();
|
||||
|
||||
d = 0.0;
|
||||
v = nan(""); // FP_NAN
|
||||
for (int i = 0; i < iters; ++i) {
|
||||
d += fpclassify(v);
|
||||
}
|
||||
|
||||
StopBenchmarkTiming();
|
||||
}
|
||||
BENCHMARK(BM_math_fpclassify_NAN);
|
||||
|
||||
static void BM_math_fpclassify_INFINITE(int iters) {
|
||||
StartBenchmarkTiming();
|
||||
|
||||
d = 0.0;
|
||||
v = HUGE_VAL; // FP_INFINITE
|
||||
for (int i = 0; i < iters; ++i) {
|
||||
d += fpclassify(v);
|
||||
}
|
||||
|
||||
StopBenchmarkTiming();
|
||||
}
|
||||
BENCHMARK(BM_math_fpclassify_INFINITE);
|
||||
|
||||
static void BM_math_fpclassify_ZERO(int iters) {
|
||||
StartBenchmarkTiming();
|
||||
|
||||
d = 0.0;
|
||||
v = 0.0; // FP_ZERO
|
||||
for (int i = 0; i < iters; ++i) {
|
||||
d += fpclassify(v);
|
||||
}
|
||||
|
||||
StopBenchmarkTiming();
|
||||
}
|
||||
BENCHMARK(BM_math_fpclassify_ZERO);
|
||||
|
@ -132,6 +132,7 @@ libc_bionic_src_files := \
|
||||
bionic/ffs.cpp \
|
||||
bionic/flockfile.cpp \
|
||||
bionic/fork.cpp \
|
||||
bionic/fpclassify.cpp \
|
||||
bionic/futimens.cpp \
|
||||
bionic/getauxval.cpp \
|
||||
bionic/getcwd.cpp \
|
||||
@ -547,7 +548,7 @@ LOCAL_SRC_FILES := $(libc_upstream_freebsd_src_files)
|
||||
LOCAL_CFLAGS := \
|
||||
$(libc_common_cflags) \
|
||||
-I$(LOCAL_PATH)/upstream-freebsd \
|
||||
-I$(LOCAL_PATH)/upstream-freebsd/libc/include \
|
||||
-I$(LOCAL_PATH)/upstream-freebsd/lib/libc/include \
|
||||
-include upstream-freebsd/freebsd-compat.h
|
||||
LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
|
||||
LOCAL_CPPFLAGS := $(libc_common_cppflags)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ieee.h,v 1.1 2004/02/01 05:09:49 drahn Exp $ */
|
||||
/* $OpenBSD: ieee.h,v 1.4 2011/11/08 17:06:51 deraadt Exp $ */
|
||||
/* $NetBSD: ieee.h,v 1.2 2001/02/21 17:43:50 bjh21 Exp $ */
|
||||
|
||||
/*
|
||||
@ -92,35 +92,36 @@
|
||||
#define SNG_FRACBITS 23
|
||||
|
||||
#define DBL_EXPBITS 11
|
||||
#define DBL_FRACHBITS 20
|
||||
#define DBL_FRACLBITS 32
|
||||
#define DBL_FRACBITS 52
|
||||
|
||||
#ifndef __VFP_FP__
|
||||
#define E80_EXPBITS 15
|
||||
#define E80_FRACHBITS 31
|
||||
#define E80_FRACLBITS 32
|
||||
#define E80_FRACBITS 64
|
||||
|
||||
#define EXT_EXPBITS 15
|
||||
#define EXT_FRACHBITS 16
|
||||
#define EXT_FRACHMBITS 32
|
||||
#define EXT_FRACLMBITS 32
|
||||
#define EXT_FRACLBITS 32
|
||||
#define EXT_FRACBITS 112
|
||||
#endif
|
||||
|
||||
struct ieee_single {
|
||||
u_int sng_frac:23;
|
||||
u_int sng_exponent:8;
|
||||
u_int sng_exp:8;
|
||||
u_int sng_sign:1;
|
||||
};
|
||||
|
||||
#ifdef __VFP_FP__
|
||||
struct ieee_double {
|
||||
#ifdef __ARMEB__
|
||||
u_int dbl_sign:1;
|
||||
u_int dbl_exp:11;
|
||||
u_int dbl_frach:20;
|
||||
u_int dbl_fracl;
|
||||
#else /* !__ARMEB__ */
|
||||
u_int dbl_fracl;
|
||||
u_int dbl_frach:20;
|
||||
u_int dbl_exp:11;
|
||||
u_int dbl_sign:1;
|
||||
#endif /* !__ARMEB__ */
|
||||
};
|
||||
#else /* !__VFP_FP__ */
|
||||
struct ieee_double {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ieee.h,v 1.1 2004/02/01 05:09:49 drahn Exp $ */
|
||||
/* $OpenBSD: ieee.h,v 1.4 2011/11/08 17:06:51 deraadt Exp $ */
|
||||
/* $NetBSD: ieee.h,v 1.2 2001/02/21 17:43:50 bjh21 Exp $ */
|
||||
|
||||
/*
|
||||
@ -92,35 +92,36 @@
|
||||
#define SNG_FRACBITS 23
|
||||
|
||||
#define DBL_EXPBITS 11
|
||||
#define DBL_FRACHBITS 20
|
||||
#define DBL_FRACLBITS 32
|
||||
#define DBL_FRACBITS 52
|
||||
|
||||
#ifndef __VFP_FP__
|
||||
#define E80_EXPBITS 15
|
||||
#define E80_FRACHBITS 31
|
||||
#define E80_FRACLBITS 32
|
||||
#define E80_FRACBITS 64
|
||||
|
||||
#define EXT_EXPBITS 15
|
||||
#define EXT_FRACHBITS 16
|
||||
#define EXT_FRACHMBITS 32
|
||||
#define EXT_FRACLMBITS 32
|
||||
#define EXT_FRACLBITS 32
|
||||
#define EXT_FRACBITS 112
|
||||
#endif
|
||||
|
||||
struct ieee_single {
|
||||
u_int sng_frac:23;
|
||||
u_int sng_exponent:8;
|
||||
u_int sng_exp:8;
|
||||
u_int sng_sign:1;
|
||||
};
|
||||
|
||||
#ifdef __VFP_FP__
|
||||
struct ieee_double {
|
||||
#ifdef __AARCH64EB__
|
||||
u_int dbl_sign:1;
|
||||
u_int dbl_exp:11;
|
||||
u_int dbl_frach:20;
|
||||
u_int dbl_fracl;
|
||||
#else /* !__AARCH64EB__ */
|
||||
u_int dbl_fracl;
|
||||
u_int dbl_frach:20;
|
||||
u_int dbl_exp:11;
|
||||
u_int dbl_sign:1;
|
||||
#endif /* !__AARCH64EB__ */
|
||||
};
|
||||
#else /* !__VFP_FP__ */
|
||||
struct ieee_double {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ieee.h,v 1.2 2003/06/02 23:27:47 millert Exp $ */
|
||||
/* $OpenBSD: ieee.h,v 1.3 2008/09/07 20:36:06 martynas Exp $ */
|
||||
/* $NetBSD: ieee.h,v 1.1 1996/09/30 16:34:25 ws Exp $ */
|
||||
|
||||
/*
|
||||
@ -79,10 +79,19 @@
|
||||
#define SNG_FRACBITS 23
|
||||
|
||||
#define DBL_EXPBITS 11
|
||||
#define DBL_FRACHBITS 20
|
||||
#define DBL_FRACLBITS 32
|
||||
#define DBL_FRACBITS 52
|
||||
|
||||
#define EXT_EXPBITS 15
|
||||
#define EXT_FRACBITS 112
|
||||
#define EXT_FRACHBITS 32
|
||||
#define EXT_FRACLBITS 32
|
||||
#define EXT_FRACBITS 64
|
||||
|
||||
#define EXT_TO_ARRAY32(p, a) do { \
|
||||
(a)[0] = (uint32_t)(p)->ext_fracl; \
|
||||
(a)[1] = (uint32_t)(p)->ext_frach; \
|
||||
} while(0)
|
||||
|
||||
struct ieee_single {
|
||||
u_int sng_frac:23;
|
||||
@ -99,11 +108,10 @@ struct ieee_double {
|
||||
|
||||
struct ieee_ext {
|
||||
u_int ext_fracl;
|
||||
u_int ext_fraclm;
|
||||
u_int ext_frachm;
|
||||
u_int ext_frach:16;
|
||||
u_int ext_frach;
|
||||
u_int ext_exp:15;
|
||||
u_int ext_sign:1;
|
||||
u_int ext_pad:16;
|
||||
};
|
||||
|
||||
/*
|
||||
|
138
libc/bionic/fpclassify.cpp
Normal file
138
libc/bionic/fpclassify.cpp
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
* 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.
|
||||
* * 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 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.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <machine/ieee.h>
|
||||
|
||||
// These aren't declared in our <math.h>.
|
||||
extern "C" int __isinf(double);
|
||||
extern "C" int __isnan(double);
|
||||
|
||||
union float_u {
|
||||
float f;
|
||||
ieee_single bits;
|
||||
};
|
||||
|
||||
union double_u {
|
||||
double d;
|
||||
ieee_double bits;
|
||||
};
|
||||
|
||||
int __fpclassifyd(double d) {
|
||||
double_u u;
|
||||
u.d = d;
|
||||
if (u.bits.dbl_exp == 0) {
|
||||
return ((u.bits.dbl_fracl | u.bits.dbl_frach) == 0) ? FP_ZERO : FP_SUBNORMAL;
|
||||
}
|
||||
if (u.bits.dbl_exp == DBL_EXP_INFNAN) {
|
||||
return ((u.bits.dbl_fracl | u.bits.dbl_frach) == 0) ? FP_INFINITE : FP_NAN;
|
||||
}
|
||||
return FP_NORMAL;
|
||||
}
|
||||
__strong_alias(__fpclassify, __fpclassifyd); // glibc uses __fpclassify, BSD __fpclassifyd.
|
||||
|
||||
int __fpclassifyf(float f) {
|
||||
float_u u;
|
||||
u.f = f;
|
||||
if (u.bits.sng_exp == 0) {
|
||||
return (u.bits.sng_frac == 0) ? FP_ZERO : FP_SUBNORMAL;
|
||||
}
|
||||
if (u.bits.sng_exp == SNG_EXP_INFNAN) {
|
||||
return (u.bits.sng_frac == 0) ? FP_INFINITE : FP_NAN;
|
||||
}
|
||||
return FP_NORMAL;
|
||||
}
|
||||
|
||||
int __isinf(double d) {
|
||||
return (__fpclassifyd(d) == FP_INFINITE);
|
||||
}
|
||||
__strong_alias(isinf, __isinf);
|
||||
|
||||
int __isinff(float f) {
|
||||
return (__fpclassifyf(f) == FP_INFINITE);
|
||||
}
|
||||
__strong_alias(isinff, __isinff);
|
||||
|
||||
int __isnan(double d) {
|
||||
return (__fpclassifyd(d) == FP_NAN);
|
||||
}
|
||||
__strong_alias(isnan, __isnan);
|
||||
|
||||
int __isnanf(float f) {
|
||||
return (__fpclassifyf(f) == FP_NAN);
|
||||
}
|
||||
__strong_alias(isnanf, __isnanf);
|
||||
|
||||
#if __LP64__
|
||||
|
||||
// LP64 uses 128-bit long doubles.
|
||||
|
||||
union long_double_u {
|
||||
long double ld;
|
||||
struct {
|
||||
unsigned long fracl:64;
|
||||
unsigned long frach:48;
|
||||
unsigned int exp:15;
|
||||
unsigned int sign:1;
|
||||
} bits;
|
||||
};
|
||||
|
||||
int __fpclassifyl(long double ld) {
|
||||
long_double_u u;
|
||||
u.ld = ld;
|
||||
if (u.bits.exp == 0) {
|
||||
return ((u.bits.fracl | u.bits.frach) == 0) ? FP_ZERO : FP_SUBNORMAL;
|
||||
}
|
||||
if (u.bits.exp == EXT_EXP_INFNAN) {
|
||||
return ((u.bits.fracl | u.bits.frach) == 0) ? FP_INFINITE : FP_NAN;
|
||||
}
|
||||
return FP_NORMAL;
|
||||
}
|
||||
|
||||
int __isinfl(long double ld) {
|
||||
return (__fpclassifyl(ld) == FP_INFINITE);
|
||||
}
|
||||
|
||||
int __isnanl(long double ld) {
|
||||
return (__fpclassifyl(ld) == FP_NAN);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// LP32 uses double as long double.
|
||||
|
||||
__strong_alias(__fpclassifyl, __fpclassify);
|
||||
__strong_alias(__isinfl, __isinf);
|
||||
__strong_alias(__isnanl, __isnan);
|
||||
|
||||
#endif
|
||||
|
||||
__strong_alias(isinfl, __isinfl);
|
||||
__strong_alias(isnanl, __isnanl);
|
@ -154,12 +154,6 @@ static int exponent(char *, int, int);
|
||||
|
||||
#define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */
|
||||
|
||||
/* BIONIC: do not link libm for only two rather simple functions */
|
||||
#ifdef FLOATING_POINT
|
||||
static int _my_isinf(double);
|
||||
static int _my_isnan(double);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macros for converting digits to letters and vice versa
|
||||
*/
|
||||
@ -543,14 +537,14 @@ reswitch: switch (ch) {
|
||||
}
|
||||
|
||||
/* do this before tricky precision changes */
|
||||
if (_my_isinf(_double)) {
|
||||
if (isinf(_double)) {
|
||||
if (_double < 0)
|
||||
sign = '-';
|
||||
cp = "Inf";
|
||||
size = 3;
|
||||
break;
|
||||
}
|
||||
if (_my_isnan(_double)) {
|
||||
if (isnan(_double)) {
|
||||
cp = "NaN";
|
||||
size = 3;
|
||||
break;
|
||||
@ -1331,29 +1325,4 @@ exponent(char *p0, int exp, int fmtch)
|
||||
return (p - p0);
|
||||
}
|
||||
|
||||
|
||||
/* BIONIC */
|
||||
#include <machine/ieee.h>
|
||||
typedef union {
|
||||
double d;
|
||||
struct ieee_double i;
|
||||
} ieee_u;
|
||||
|
||||
static int
|
||||
_my_isinf (double value)
|
||||
{
|
||||
ieee_u u;
|
||||
|
||||
u.d = value;
|
||||
return (u.i.dbl_exp == 2047 && u.i.dbl_frach == 0 && u.i.dbl_fracl == 0);
|
||||
}
|
||||
|
||||
static int
|
||||
_my_isnan (double value)
|
||||
{
|
||||
ieee_u u;
|
||||
|
||||
u.d = value;
|
||||
return (u.i.dbl_exp == 2047 && (u.i.dbl_frach != 0 || u.i.dbl_fracl != 0));
|
||||
}
|
||||
#endif /* FLOATING_POINT */
|
||||
|
@ -1,10 +1,10 @@
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
# TODO: these come from from upstream's libc, not libm!
|
||||
# TODO: this comes from from upstream's libc, not libm, but it's an
|
||||
# implementation detail that should have hidden visibility, so it needs
|
||||
# to be in whatever library the math code is in.
|
||||
libm_common_src_files := \
|
||||
digittoint.c \
|
||||
fpclassify.c \
|
||||
isinf.c \
|
||||
|
||||
# TODO: this is not in the BSDs.
|
||||
libm_common_src_files += \
|
||||
@ -129,7 +129,6 @@ libm_common_src_files += \
|
||||
upstream-freebsd/lib/msun/src/s_ilogb.c \
|
||||
upstream-freebsd/lib/msun/src/s_ilogbf.c \
|
||||
upstream-freebsd/lib/msun/src/s_isfinite.c \
|
||||
upstream-freebsd/lib/msun/src/s_isnan.c \
|
||||
upstream-freebsd/lib/msun/src/s_isnormal.c \
|
||||
upstream-freebsd/lib/msun/src/s_llrint.c \
|
||||
upstream-freebsd/lib/msun/src/s_llrintf.c \
|
||||
@ -237,6 +236,7 @@ libm_common_cflags := \
|
||||
-include $(LOCAL_PATH)/freebsd-compat.h \
|
||||
|
||||
libm_common_includes := $(LOCAL_PATH)/upstream-freebsd/lib/msun/src/
|
||||
|
||||
libm_ld_includes := $(LOCAL_PATH)/upstream-freebsd/lib/msun/ld128/
|
||||
|
||||
#
|
||||
|
@ -17,11 +17,6 @@
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
|
||||
extern int __isinf(double); /* isinf.c */
|
||||
int (isinf)(double a1) { return __isinf(a1); }
|
||||
|
||||
int (isnanf)(float a1) { return __isnanf(a1); }
|
||||
|
||||
/*
|
||||
* On LP64 sizeof(long double) > sizeof(double) so functions which fall back
|
||||
* to their double variants lose precision. Emit a warning whenever something
|
||||
@ -58,10 +53,7 @@ WARN_IMPRECISE(powl)
|
||||
* that call the regular "double" function.
|
||||
*/
|
||||
|
||||
int __fpclassifyl(long double a1) { return __fpclassifyd(a1); }
|
||||
int __isfinitel(long double a1) { return __isfinite(a1); }
|
||||
int __isinfl(long double a1) { return __isinf(a1); }
|
||||
int __isnanl(long double a1) { return (isnan)(a1); }
|
||||
int __isnormall(long double a1) { return __isnormal(a1); }
|
||||
int __signbitl(long double a1) { return __signbit(a1); }
|
||||
|
||||
|
@ -1,94 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Mike Barcroft <mike@FreeBSD.org>
|
||||
* Copyright (c) 2002, 2003 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: src/lib/libc/gen/fpclassify.c,v 1.2 2005/02/06 03:23:31 das Exp $
|
||||
*/
|
||||
|
||||
#include <sys/endian.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "fpmath.h"
|
||||
|
||||
int
|
||||
__fpclassifyf(float f)
|
||||
{
|
||||
union IEEEf2bits u;
|
||||
|
||||
u.f = f;
|
||||
if (u.bits.exp == 0) {
|
||||
if (u.bits.man == 0)
|
||||
return (FP_ZERO);
|
||||
return (FP_SUBNORMAL);
|
||||
}
|
||||
if (u.bits.exp == 255) {
|
||||
if (u.bits.man == 0)
|
||||
return (FP_INFINITE);
|
||||
return (FP_NAN);
|
||||
}
|
||||
return (FP_NORMAL);
|
||||
}
|
||||
|
||||
int
|
||||
__fpclassifyd(double d)
|
||||
{
|
||||
union IEEEd2bits u;
|
||||
|
||||
u.d = d;
|
||||
if (u.bits.exp == 0) {
|
||||
if ((u.bits.manl | u.bits.manh) == 0)
|
||||
return (FP_ZERO);
|
||||
return (FP_SUBNORMAL);
|
||||
}
|
||||
if (u.bits.exp == 2047) {
|
||||
if ((u.bits.manl | u.bits.manh) == 0)
|
||||
return (FP_INFINITE);
|
||||
return (FP_NAN);
|
||||
}
|
||||
return (FP_NORMAL);
|
||||
}
|
||||
|
||||
int
|
||||
__fpclassifyl(long double e)
|
||||
{
|
||||
union IEEEl2bits u;
|
||||
|
||||
u.e = e;
|
||||
if (u.bits.exp == 0) {
|
||||
if ((u.bits.manl | u.bits.manh) == 0)
|
||||
return (FP_ZERO);
|
||||
return (FP_SUBNORMAL);
|
||||
}
|
||||
mask_nbit_l(u); /* Mask normalization bit if applicable. */
|
||||
if (u.bits.exp == 32767) {
|
||||
if ((u.bits.manl | u.bits.manh) == 0)
|
||||
return (FP_INFINITE);
|
||||
return (FP_NAN);
|
||||
}
|
||||
return (FP_NORMAL);
|
||||
}
|
||||
|
68
libm/isinf.c
68
libm/isinf.c
@ -1,68 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2004 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$
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include "fpmath.h"
|
||||
|
||||
/*
|
||||
* XXX These routines belong in libm, but they must remain in libc for
|
||||
* binary compat until we can bump libm's major version number.
|
||||
*/
|
||||
|
||||
int
|
||||
__isinf(double d)
|
||||
{
|
||||
union IEEEd2bits u;
|
||||
|
||||
u.d = d;
|
||||
return (u.bits.exp == 2047 && u.bits.manl == 0 && u.bits.manh == 0);
|
||||
}
|
||||
|
||||
int
|
||||
__isinff(float f)
|
||||
{
|
||||
union IEEEf2bits u;
|
||||
|
||||
u.f = f;
|
||||
return (u.bits.exp == 255 && u.bits.man == 0);
|
||||
}
|
||||
|
||||
int
|
||||
__isinfl(long double e)
|
||||
{
|
||||
union IEEEl2bits u;
|
||||
|
||||
u.e = e;
|
||||
mask_nbit_l(u);
|
||||
#ifndef __alpha__
|
||||
return (u.bits.exp == 32767 && u.bits.manl == 0 && u.bits.manh == 0);
|
||||
#else
|
||||
return (u.bits.exp == 2047 && u.bits.manl == 0 && u.bits.manh == 0);
|
||||
#endif
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2004 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$
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "fpmath.h"
|
||||
|
||||
/* Provided by libc.so */
|
||||
#ifndef PIC
|
||||
#undef isnan
|
||||
int
|
||||
isnan(double d)
|
||||
{
|
||||
union IEEEd2bits u;
|
||||
|
||||
u.d = d;
|
||||
return (u.bits.exp == 2047 && (u.bits.manl != 0 || u.bits.manh != 0));
|
||||
}
|
||||
#endif /* !PIC */
|
||||
|
||||
int
|
||||
__isnanf(float f)
|
||||
{
|
||||
union IEEEf2bits u;
|
||||
|
||||
u.f = f;
|
||||
return (u.bits.exp == 255 && u.bits.man != 0);
|
||||
}
|
||||
|
||||
int
|
||||
__isnanl(long double e)
|
||||
{
|
||||
union IEEEl2bits u;
|
||||
|
||||
u.e = e;
|
||||
mask_nbit_l(u);
|
||||
return (u.bits.exp == 32767 && (u.bits.manl != 0 || u.bits.manh != 0));
|
||||
}
|
||||
|
||||
__weak_reference(__isnanf, isnanf);
|
@ -239,6 +239,12 @@ TEST(math, finite) {
|
||||
ASSERT_FALSE(finite(HUGE_VAL));
|
||||
}
|
||||
|
||||
TEST(math, isinf_function) {
|
||||
// The isinf macro deals with all three types; the isinf function is for doubles.
|
||||
ASSERT_FALSE((isinf)(123.0));
|
||||
ASSERT_TRUE((isinf)(HUGE_VAL));
|
||||
}
|
||||
|
||||
TEST(math, __isinff) {
|
||||
ASSERT_FALSE(__isinff(123.0f));
|
||||
ASSERT_TRUE(__isinff(HUGE_VALF));
|
||||
@ -249,6 +255,12 @@ TEST(math, __isinfl) {
|
||||
ASSERT_TRUE(__isinfl(HUGE_VALL));
|
||||
}
|
||||
|
||||
TEST(math, isnan_function) {
|
||||
// The isnan macro deals with all three types; the isnan function is for doubles.
|
||||
ASSERT_FALSE((isnan)(123.0));
|
||||
ASSERT_TRUE((isnan)(nan("")));
|
||||
}
|
||||
|
||||
TEST(math, __isnanf) {
|
||||
ASSERT_FALSE(__isnanf(123.0f));
|
||||
ASSERT_TRUE(__isnanf(nanf("")));
|
||||
|
Loading…
Reference in New Issue
Block a user