📄 floatlib.c
字号:
float__floatdisf (register long long a1){ return (float)__floatdidf(a1);}/* negate a float */float__negsf2 (float a1){ register union float_long fl1; fl1.f = a1; if (!fl1.l) return (0); fl1.l ^= SIGNBIT; return (fl1.f);}/* negate a double */double__negdf2 (double a1){ register union double_long dl1; dl1.d = a1; if (!dl1.l.upper && !dl1.l.lower) return (dl1.d); dl1.l.upper ^= SIGNBIT; return (dl1.d);}/* convert float to double */double__extendsfdf2 (float a1){ register union float_long fl1; register union double_long dl; register int exp; fl1.f = a1; if (!fl1.l) { dl.l.upper = dl.l.lower = 0; return (dl.d); } dl.l.upper = SIGN (fl1.l); exp = EXP (fl1.l) - EXCESS + EXCESSD; dl.l.upper |= exp << 20; dl.l.upper |= (MANT (fl1.l) & ~HIDDEN) >> 3; dl.l.lower = MANT (fl1.l) << 29; return (dl.d);}/* compare two doubles */long__cmpdf2 (double a1, double a2){ register union double_long dl1, dl2; dl1.d = a1; dl2.d = a2; if (SIGND (dl1) && SIGND (dl2)) { dl1.l.upper ^= SIGNBIT; dl2.l.upper ^= SIGNBIT; if (dl1.l.upper < dl2.l.upper) return (1); if (dl1.l.upper > dl2.l.upper) return (-1); if (dl1.l.lower < dl2.l.lower) return (1); if (dl1.l.lower > dl2.l.lower) return (-1); return (0); } else { if (dl1.l.upper < dl2.l.upper) return (-1); if (dl1.l.upper > dl2.l.upper) return (1); if (dl1.l.lower < dl2.l.lower) return (-1); if (dl1.l.lower > dl2.l.lower) return (1); return (0); }}/* convert double to int */long__fixdfsi (double a1){ register union double_long dl1; register int exp; register long l; dl1.d = a1; if (!dl1.l.upper && !dl1.l.lower) return (0); exp = EXPD (dl1) - EXCESSD - 31; l = MANTD (dl1); if (exp > 0) return SIGND(dl1) ? (1<<31) : ((1ul<<31)-1); /* shift down until exp = 0 or l = 0 */ if (exp <= 0 && exp > -32 && l) l >>= -exp; else return (0); return (SIGND (dl1) ? -l : l);}/* convert float to int */long__fixsfsi (float a1){ return __fixdfsi(__extendsfdf2(a1));}/* convert double to int */long long__fixdfdi (double a1){ register union double_long dl1; register int exp; register long long l; dl1.d = a1; if (!dl1.l.upper && !dl1.l.lower) return (0); exp = EXPD (dl1) - EXCESSD - 64; l = MANTD_LL(dl1); if (exp > 0) { l = (long long)1<<63; if (!SIGND(dl1)) l--; return l; } /* shift down until exp = 0 or l = 0 */ if (exp <= 0 && exp > -64 && l) l >>= -exp; else return (0); return (SIGND (dl1) ? -l : l);}/* convert double to unsigned int */unsigned long__fixunsdfsi (double a1){ register union double_long dl1; register int exp; register unsigned long l; dl1.d = a1; if (!dl1.l.upper && !dl1.l.lower) return (0); exp = EXPD (dl1) - EXCESSD - 32; l = (((((dl1.l.upper) & 0xFFFFF) | HIDDEND) << 11) | (dl1.l.lower >> 21)); if (exp > 0) return (0xFFFFFFFFul); /* largest integer */ /* shift down until exp = 0 or l = 0 */ if (exp < 0 && exp > -32 && l) l >>= -exp; else return (0); return (l);}/* convert double to unsigned int */unsigned long long__fixunsdfdi (double a1){ register union double_long dl1; register int exp; register unsigned long long l; dl1.d = a1; if (dl1.ll == 0) return (0); exp = EXPD (dl1) - EXCESSD - 64; l = dl1.ll; if (exp > 0) return (unsigned long long)-1; /* shift down until exp = 0 or l = 0 */ if (exp < 0 && exp > -64 && l) l >>= -exp; else return (0); return (l);}/* addtwo doubles */double__adddf3 (double a1, double a2){ register long long mant1, mant2; register union double_long fl1, fl2; register int exp1, exp2; int sign = 0; fl1.d = a1; fl2.d = a2; /* check for zero args */ if (!fl2.ll) goto test_done; if (!fl1.ll) { fl1.d = fl2.d; goto test_done; } exp1 = EXPD(fl1); exp2 = EXPD(fl2); if (exp1 > exp2 + 54) goto test_done; if (exp2 > exp1 + 54) { fl1.d = fl2.d; goto test_done; } /* do everything in excess precision so's we can round later */ mant1 = MANTD_LL(fl1) << 9; mant2 = MANTD_LL(fl2) << 9; if (SIGND(fl1)) mant1 = -mant1; if (SIGND(fl2)) mant2 = -mant2; if (exp1 > exp2) mant2 >>= exp1 - exp2; else { mant1 >>= exp2 - exp1; exp1 = exp2; } mant1 += mant2; if (mant1 < 0) { mant1 = -mant1; sign = SIGNBIT; } else if (!mant1) { fl1.d = 0; goto test_done; } /* normalize up */ while (!(mant1 & ((long long)7<<61))) { mant1 <<= 1; exp1--; } /* normalize down? */ if (mant1 & ((long long)3<<62)) { mant1 >>= 1; exp1++; } /* round to even */ mant1 += (mant1 & (1<<9)) ? (1<<8) : ((1<<8)-1); /* normalize down? */ if (mant1 & ((long long)3<<62)) { mant1 >>= 1; exp1++; } /* lose extra precision */ mant1 >>= 9; /* turn off hidden bit */ mant1 &= ~HIDDEND_LL; /* pack up and go home */ fl1.ll = PACKD_LL(sign,exp1,mant1);test_done: return (fl1.d);}/* subtract two doubles */double__subdf3 (double a1, double a2){ register union double_long fl1, fl2; fl1.d = a1; fl2.d = a2; /* check for zero args */ if (!fl2.ll) return (fl1.d); /* twiddle sign bit and add */ fl2.l.upper ^= SIGNBIT; if (!fl1.ll) return (fl2.d); return __adddf3 (a1, fl2.d);}/* multiply two doubles */double__muldf3 (double a1, double a2){ register union double_long fl1, fl2; register unsigned long long result=0ULL; register int exp; int sign; fl1.d = a1; fl2.d = a2; if (!fl1.ll || !fl2.ll) { fl1.d = 0; goto test_done; } /* compute sign and exponent */ sign = SIGND(fl1) ^ SIGND(fl2); exp = EXPD(fl1) - EXCESSD; exp += EXPD(fl2); fl1.ll = MANTD_LL(fl1); fl2.ll = MANTD_LL(fl2); /* the multiply is done as one 31x31 multiply and two 31x21 multiples */ result = (fl1.ll >> 21) * (fl2.ll >> 21); result += ((fl1.ll & 0x1FFFFF) * (fl2.ll >> 21)) >> 21; result += ((fl2.ll & 0x1FFFFF) * (fl1.ll >> 21)) >> 21; result >>= 2; if (result & ((long long)1<<61)) { /* round */ result += 1<<8; result >>= 9; } else { /* round */ result += 1<<7; result >>= 8; exp--; } if (result & (HIDDEND_LL<<1)) { result >>= 1; exp++; } result &= ~HIDDEND_LL; /* pack up and go home */ fl1.ll = PACKD_LL(sign,exp,result);test_done: return (fl1.d);}/* divide two doubles */double__divdf3 (double a1, double a2){ register union double_long fl1, fl2; register long long mask,result; register int exp, sign; fl1.d = a1; fl2.d = a2; /* subtract exponents */ exp = EXPD(fl1) - EXPD(fl2) + EXCESSD; /* compute sign */ sign = SIGND(fl1) ^ SIGND(fl2); /* numerator zero??? */ if (fl1.ll == 0) { /* divide by zero??? */ if (fl2.ll == 0) fl1.ll = ((unsigned long long)1<<63)-1; /* NaN */ else fl1.ll = 0; goto test_done; } /* return +Inf or -Inf */ if (fl2.ll == 0) { fl1.ll = PACKD_LL(SIGND(fl1),2047,0); goto test_done; } /* now get mantissas */ fl1.ll = MANTD_LL(fl1); fl2.ll = MANTD_LL(fl2); /* this assures we have 54 bits of precision in the end */ if (fl1.ll < fl2.ll) { fl1.ll <<= 1; exp--; } /* now we perform repeated subtraction of fl2.ll from fl1.ll */ mask = (long long)1<<53; result = 0; while (mask) { if (fl1.ll >= fl2.ll) { result |= mask; fl1.ll -= fl2.ll; } fl1.ll <<= 1; mask >>= 1; } /* round */ result += 1; /* normalize down */ exp++; result >>= 1; result &= ~HIDDEND_LL; /* pack up and go home */ fl1.ll = PACKD_LL(sign, exp, result);test_done: return (fl1.d);}int__gtdf2 (double a1, double a2){ return __cmpdf2 ((float) a1, (float) a2) > 0;}int__gedf2 (double a1, double a2){ return (__cmpdf2 ((float) a1, (float) a2) >= 0) - 1;}int__ltdf2 (double a1, double a2){ return - (__cmpdf2 ((float) a1, (float) a2) < 0);}int__ledf2 (double a1, double a2){ return __cmpdf2 ((float) a1, (float) a2) > 0;}int__eqdf2 (double a1, double a2){ return *(long long *) &a1 == *(long long *) &a2;}int__nedf2 (double a1, double a2){ return *(long long *) &a1 != *(long long *) &a2;}/* absolute value of double */double__absdf2(double a1){ if (__cmpdf2(a1,0.0) < 0) return __negdf2(a1); else return a1;}/* absolute value of float */float__abssf2(float a1){ if (__cmpsf2(a1,0.0) < 0) return __negsf2(a1); else return a1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -