Path: blob/master/src/java.base/share/native/libfdlibm/e_remainder.c
41149 views
/*1* Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425/* __ieee754_remainder(x,p)26* Return :27* returns x REM p = x - [x/p]*p as if in infinite28* precise arithmetic, where [x/p] is the (infinite bit)29* integer nearest x/p (in half way case choose the even one).30* Method :31* Based on fmod() return x-[x/p]chopped*p exactlp.32*/3334#include "fdlibm.h"3536#ifdef __STDC__37static const double zero = 0.0;38#else39static double zero = 0.0;40#endif414243#ifdef __STDC__44double __ieee754_remainder(double x, double p)45#else46double __ieee754_remainder(x,p)47double x,p;48#endif49{50int hx,hp;51unsigned sx,lx,lp;52double p_half;5354hx = __HI(x); /* high word of x */55lx = __LO(x); /* low word of x */56hp = __HI(p); /* high word of p */57lp = __LO(p); /* low word of p */58sx = hx&0x80000000;59hp &= 0x7fffffff;60hx &= 0x7fffffff;6162/* purge off exception values */63if((hp|lp)==0) return (x*p)/(x*p); /* p = 0 */64if((hx>=0x7ff00000)|| /* x not finite */65((hp>=0x7ff00000)&& /* p is NaN */66(((hp-0x7ff00000)|lp)!=0)))67return (x*p)/(x*p);686970if (hp<=0x7fdfffff) x = __ieee754_fmod(x,p+p); /* now x < 2p */71if (((hx-hp)|(lx-lp))==0) return zero*x;72x = fabs(x);73p = fabs(p);74if (hp<0x00200000) {75if(x+x>p) {76x-=p;77if(x+x>=p) x -= p;78}79} else {80p_half = 0.5*p;81if(x>p_half) {82x-=p;83if(x>=p_half) x -= p;84}85}86__HI(x) ^= sx;87return x;88}899091