File: | src/lib/libm/src/e_fmodf.c |
Warning: | line 92, column 37 The result of the left shift is undefined because the left operand is negative |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* e_fmodf.c -- float version of e_fmod.c. | |||
2 | * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. | |||
3 | */ | |||
4 | ||||
5 | /* | |||
6 | * ==================================================== | |||
7 | * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. | |||
8 | * | |||
9 | * Developed at SunPro, a Sun Microsystems, Inc. business. | |||
10 | * Permission to use, copy, modify, and distribute this | |||
11 | * software is freely granted, provided that this notice | |||
12 | * is preserved. | |||
13 | * ==================================================== | |||
14 | */ | |||
15 | ||||
16 | /* | |||
17 | * fmodf(x,y) | |||
18 | * Return x mod y in exact arithmetic | |||
19 | * Method: shift and subtract | |||
20 | */ | |||
21 | ||||
22 | #include "math.h" | |||
23 | #include "math_private.h" | |||
24 | ||||
25 | static const float one = 1.0, Zero[] = {0.0, -0.0,}; | |||
26 | ||||
27 | float | |||
28 | fmodf(float x, float y) | |||
29 | { | |||
30 | int32_t n,hx,hy,hz,ix,iy,sx,i; | |||
31 | ||||
32 | GET_FLOAT_WORD(hx,x)do { ieee_float_shape_type gf_u; gf_u.value = (x); (hx) = gf_u .word; } while (0); | |||
| ||||
33 | GET_FLOAT_WORD(hy,y)do { ieee_float_shape_type gf_u; gf_u.value = (y); (hy) = gf_u .word; } while (0); | |||
34 | sx = hx&0x80000000; /* sign of x */ | |||
35 | hx ^=sx; /* |x| */ | |||
36 | hy &= 0x7fffffff; /* |y| */ | |||
37 | ||||
38 | /* purge off exception values */ | |||
39 | if(hy==0||(hx>=0x7f800000)|| /* y=0,or x not finite */ | |||
40 | (hy>0x7f800000)) /* or y is NaN */ | |||
41 | return (x*y)/(x*y); | |||
42 | if(hx<hy) return x; /* |x|<|y| return x */ | |||
43 | if(hx==hy) | |||
44 | return Zero[(u_int32_t)sx>>31]; /* |x|=|y| return x*0*/ | |||
45 | ||||
46 | /* determine ix = ilogb(x) */ | |||
47 | if(hx<0x00800000) { /* subnormal x */ | |||
48 | for (ix = -126,i=(hx<<8); i>0; i<<=1) ix -=1; | |||
49 | } else ix = (hx>>23)-127; | |||
50 | ||||
51 | /* determine iy = ilogb(y) */ | |||
52 | if(hy<0x00800000) { /* subnormal y */ | |||
53 | for (iy = -126,i=(hy<<8); i>=0; i<<=1) iy -=1; | |||
54 | } else iy = (hy>>23)-127; | |||
55 | ||||
56 | /* set up {hx,lx}, {hy,ly} and align y to x */ | |||
57 | if(ix >= -126) | |||
58 | hx = 0x00800000|(0x007fffff&hx); | |||
59 | else { /* subnormal x, shift x to normal */ | |||
60 | n = -126-ix; | |||
61 | hx = hx<<n; | |||
62 | } | |||
63 | if(iy >= -126) | |||
64 | hy = 0x00800000|(0x007fffff&hy); | |||
65 | else { /* subnormal y, shift y to normal */ | |||
66 | n = -126-iy; | |||
67 | hy = hy<<n; | |||
68 | } | |||
69 | ||||
70 | /* fix point fmod */ | |||
71 | n = ix - iy; | |||
72 | while(n--) { | |||
73 | hz=hx-hy; | |||
74 | if(hz<0){hx = hx+hx;} | |||
75 | else { | |||
76 | if(hz==0) /* return sign(x)*0 */ | |||
77 | return Zero[(u_int32_t)sx>>31]; | |||
78 | hx = hz+hz; | |||
79 | } | |||
80 | } | |||
81 | hz=hx-hy; | |||
82 | if(hz>=0) {hx=hz;} | |||
83 | ||||
84 | /* convert back to floating value and restore the sign */ | |||
85 | if(hx==0) /* return sign(x)*0 */ | |||
86 | return Zero[(u_int32_t)sx>>31]; | |||
87 | while(hx<0x00800000) { /* normalize x */ | |||
88 | hx = hx+hx; | |||
89 | iy -= 1; | |||
90 | } | |||
91 | if(iy>= -126) { /* normalize output */ | |||
92 | hx = ((hx-0x00800000)|((iy+127)<<23)); | |||
| ||||
93 | SET_FLOAT_WORD(x,hx|sx)do { ieee_float_shape_type sf_u; sf_u.word = (hx|sx); (x) = sf_u .value; } while (0); | |||
94 | } else { /* subnormal output */ | |||
95 | n = -126 - iy; | |||
96 | hx >>= n; | |||
97 | SET_FLOAT_WORD(x,hx|sx)do { ieee_float_shape_type sf_u; sf_u.word = (hx|sx); (x) = sf_u .value; } while (0); | |||
98 | x *= one; /* create necessary signal */ | |||
99 | } | |||
100 | return x; /* exact output */ | |||
101 | } | |||
102 | DEF_STD(fmodf)__asm__(".global " "fmodf" " ; " "fmodf" " = " "_libm_fmodf"); |