mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-27 07:20:11 +00:00
b74d259fe7
The alpha specific version of trunc and truncf always add and subtract 0x1.0p23 or 0x1.0p52 even for big values. This causes this kind of errors in the testsuite: Failure: Test: trunc_towardzero (0x1p107) Result: is: 1.6225927682921334e+32 0x1.fffffffffffffp+106 should be: 1.6225927682921336e+32 0x1.0000000000000p+107 difference: 1.8014398509481984e+16 0x1.0000000000000p+54 ulp : 0.5000 max.ulp : 0.0000 Change this by returning the input value when its absolute value is greater than 0x1.0p23 or 0x1.0p52. NaN have to go through the add and subtract operations to get possibly silenced. Finally remove the code to handle inexact exception, trunc should never generate such an exception. Changelog: * sysdeps/alpha/fpu/s_trunc.c (__trunc): Return the input value when its absolute value is greater than 0x1.0p52. [_IEEE_FP_INEXACT] Remove. * sysdeps/alpha/fpu/s_truncf.c (__truncf): Return the input value when its absolute value is greater than 0x1.0p23. [_IEEE_FP_INEXACT] Remove.
52 lines
1.5 KiB
C
52 lines
1.5 KiB
C
/* Copyright (C) 2007-2016 Free Software Foundation, Inc.
|
|
This file is part of the GNU C Library.
|
|
Contributed by Richard Henderson.
|
|
|
|
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
|
|
<http://www.gnu.org/licenses/>. */
|
|
|
|
#include <math.h>
|
|
#include <math_ldbl_opt.h>
|
|
|
|
|
|
/* Use the chopped rounding mode conversion instructions to implement trunc. */
|
|
|
|
double
|
|
__trunc (double x)
|
|
{
|
|
double two52 = copysign (0x1.0p52, x);
|
|
double r, tmp;
|
|
|
|
if (isgreaterequal (fabs (x), 0x1.0p52))
|
|
return x;
|
|
|
|
__asm (
|
|
"addt/suc %2, %3, %1\n\tsubt/suc %1, %3, %0"
|
|
: "=&f"(r), "=&f"(tmp)
|
|
: "f"(x), "f"(two52));
|
|
|
|
/* trunc(-0) == -0, and in general we'll always have the same
|
|
sign as our input. */
|
|
return copysign (r, x);
|
|
}
|
|
|
|
weak_alias (__trunc, trunc)
|
|
#ifdef NO_LONG_DOUBLE
|
|
strong_alias (__trunc, __truncl)
|
|
weak_alias (__trunc, truncl)
|
|
#endif
|
|
#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
|
|
compat_symbol (libm, __trunc, truncl, GLIBC_2_1);
|
|
#endif
|