syscons util remove use kbdcontrol & vidcontrol instead
[unix-history] / lib / msun / src / e_remainder.c
CommitLineData
4acf9396
GCI
1/* @(#)e_remainder.c 5.1 93/09/24 */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunPro, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12
13#ifndef lint
14static char rcsid[] = "$Id: e_remainder.c,v 1.4 1994/03/03 17:04:20 jtc Exp $";
15#endif
16
17/* __ieee754_remainder(x,p)
18 * Return :
19 * returns x REM p = x - [x/p]*p as if in infinite
20 * precise arithmetic, where [x/p] is the (infinite bit)
21 * integer nearest x/p (in half way case choose the even one).
22 * Method :
23 * Based on fmod() return x-[x/p]chopped*p exactlp.
24 */
25
26#include "math.h"
27#include <machine/endian.h>
28
29#if BYTE_ORDER == LITTLE_ENDIAN
30#define n0 1
31#define n1 0
32#else
33#define n0 0
34#define n1 1
35#endif
36
37#ifdef __STDC__
38static const double zero = 0.0;
39#else
40static double zero = 0.0;
41#endif
42
43
44#ifdef __STDC__
45 double __ieee754_remainder(double x, double p)
46#else
47 double __ieee754_remainder(x,p)
48 double x,p;
49#endif
50{
51 int hx,hp;
52 unsigned sx,lx,lp;
53 double p_half;
54
55 hx = *( n0 + (int*)&x); /* high word of x */
56 lx = *( n1 + (int*)&x); /* low word of x */
57 hp = *( n0 + (int*)&p); /* high word of p */
58 lp = *( n1 + (int*)&p); /* low word of p */
59 sx = hx&0x80000000;
60 hp &= 0x7fffffff;
61 hx &= 0x7fffffff;
62
63 /* purge off exception values */
64 if((hp|lp)==0) return (x*p)/(x*p); /* p = 0 */
65 if((hx>=0x7ff00000)|| /* x not finite */
66 ((hp>=0x7ff00000)&& /* p is NaN */
67 (((hp-0x7ff00000)|lp)!=0)))
68 return (x*p)/(x*p);
69
70
71 if (hp<=0x7fdfffff) x = __ieee754_fmod(x,p+p); /* now x < 2p */
72 if (((hx-hp)|(lx-lp))==0) return zero*x;
73 x = fabs(x);
74 p = fabs(p);
75 if (hp<0x00200000) {
76 if(x+x>p) {
77 x-=p;
78 if(x+x>=p) x -= p;
79 }
80 } else {
81 p_half = 0.5*p;
82 if(x>p_half) {
83 x-=p;
84 if(x>=p_half) x -= p;
85 }
86 }
87 *(n0+(int*)&x) ^= sx;
88 return x;
89}