mirror of
git://sourceware.org/git/glibc.git
synced 2025-02-23 13:09:58 +08:00
math: Simplify hypotf implementation
Use a more optimized comparison for check for NaN and infinite and
add an inlined issignaling implementation for float. With gcc it
results in 2 FP comparisons.
The file Copyright is also changed to use GPL, the implementation was
completely changed by 7c10fd3515
to use double precision instead of
scaling and this change removes all the GET_FLOAT_WORD usage.
Checked on x86_64-linux-gnu.
This commit is contained in:
parent
5afe4c0d69
commit
7fe0ace3e2
@ -1,46 +1,39 @@
|
||||
/* e_hypotf.c -- float version of e_hypot.c.
|
||||
*/
|
||||
/* Euclidean distance function. Float/Binary32 version.
|
||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <math.h>
|
||||
#include <math_private.h>
|
||||
#include <libm-alias-finite.h>
|
||||
#include <math.h>
|
||||
#include <math-narrow-eval.h>
|
||||
#include <math_private.h>
|
||||
|
||||
float
|
||||
__ieee754_hypotf(float x, float y)
|
||||
__ieee754_hypotf (float x, float y)
|
||||
{
|
||||
double d_x, d_y;
|
||||
int32_t ha, hb;
|
||||
if (!isfinite (x) || !isfinite (y))
|
||||
{
|
||||
if ((isinf (x) || isinf (y))
|
||||
&& !issignaling (x) && !issignaling (y))
|
||||
return INFINITY;
|
||||
return x + y;
|
||||
}
|
||||
|
||||
GET_FLOAT_WORD(ha,x);
|
||||
ha &= 0x7fffffff;
|
||||
GET_FLOAT_WORD(hb,y);
|
||||
hb &= 0x7fffffff;
|
||||
if (ha == 0x7f800000 && !issignaling (y))
|
||||
return fabsf(x);
|
||||
else if (hb == 0x7f800000 && !issignaling (x))
|
||||
return fabsf(y);
|
||||
else if (ha > 0x7f800000 || hb > 0x7f800000)
|
||||
return fabsf(x) * fabsf(y);
|
||||
else if (ha == 0)
|
||||
return fabsf(y);
|
||||
else if (hb == 0)
|
||||
return fabsf(x);
|
||||
|
||||
d_x = (double) x;
|
||||
d_y = (double) y;
|
||||
|
||||
return (float) sqrt(d_x * d_x + d_y * d_y);
|
||||
return math_narrow_eval ((float) sqrt ((double) x * (double) x
|
||||
+ (double) y * (double) y));
|
||||
}
|
||||
#ifndef __ieee754_hypotf
|
||||
libm_alias_finite (__ieee754_hypotf, __hypotf)
|
||||
|
@ -101,6 +101,15 @@ asdouble (uint64_t i)
|
||||
return u.f;
|
||||
}
|
||||
|
||||
static inline int
|
||||
issignalingf_inline (float x)
|
||||
{
|
||||
uint32_t ix = asuint (x);
|
||||
if (HIGH_ORDER_BIT_IS_SET_FOR_SNAN)
|
||||
return (ix & 0x7fc00000) == 0x7fc00000;
|
||||
return 2 * (ix ^ 0x00400000) > 2 * 0x7fc00000UL;
|
||||
}
|
||||
|
||||
#define NOINLINE __attribute__ ((noinline))
|
||||
|
||||
attribute_hidden float __math_oflowf (uint32_t);
|
||||
|
Loading…
Reference in New Issue
Block a user