📄 floatlib.c
字号:
__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);}/* convert double to float */float__truncdfsf2 (double a1){ register int exp; register long mant; register union float_long fl; register union double_long dl1; dl1.d = a1; if (!dl1.l.upper && !dl1.l.lower) return (0); exp = EXPD (dl1) - EXCESSD + EXCESS; /* shift double mantissa 6 bits so we can round */ mant = MANTD (dl1) >> 6; /* now round and shift down */ mant += 1; mant >>= 1; /* did the round overflow? */ if (mant & 0xFF000000) { mant >>= 1; exp++; } mant &= ~HIDDEN; /* pack up and go home */ fl.l = PACK (SIGND (dl1), exp, mant); return (fl.f);}/* 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);}/* 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 (0x7FFFFFFF | SIGND (dl1)); /* largest integer */ /* 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 double to unsigned int */unsignedlong __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 (0xFFFFFFFF); /* largest integer */ /* shift down until exp = 0 or l = 0 */ if (exp < 0 && exp > -32 && l) l >>= -exp; else return (0); return (l);}/* For now, the hard double-precision routines simply punt and do it in single *//* addtwo doubles */double__adddf3 (double a1, double a2){ return ((float) a1 + (float) a2);}/* subtract two doubles */double__subdf3 (double a1, double a2){ return ((float) a1 - (float) a2);}/* multiply two doubles */double__muldf3 (double a1, double a2){ return ((float) a1 * (float) a2);}/* * * Name: Barrett Richardson * E-mail: barrett@iglou.com * When: Thu Dec 15 10:31:11 EST 1994 * * callable function: * * double __divdf3(double a1, double a2); * * Does software divide of a1 / a2. * * Based largely on __divsf3() in floatlib.c in the gcc * distribution. * * Purpose: To be used in conjunction with the -msoft-float * option of gcc. You should be able to tack it to the * end of floatlib.c included in the gcc distribution, * and delete the __divdf3() already there which just * calls the single precision function (or may just * use the floating point processor with some configurations). * * You may use this code for whatever your heart desires. *//* * Compare the the mantissas of two doubles. * Each mantissa is in two longs. * * return 1 if x1's mantissa is greater than x2's * -1 if x1's mantissa is less than x2's * 0 if the two mantissa's are equal. * * The Mantissas won't fit into a 4 byte word, so they are * broken up into two parts. * * This function is used internally by __divdf3() */int__dcmp (long x1m1, long x1m2, long x2m1, long x2m2){ if (x1m1 > x2m1) return 1; if (x1m1 < x2m1) return -1; /* If the first word in the two mantissas were equal check the second word */ if (x1m2 > x2m2) return 1; if (x1m2 < x2m2) return -1; return 0;}/* divide two doubles */double__divdf3 (double a1, double a2){ int sign, exponent, bit_bucket; register unsigned long mantissa1, mantissa2, x1m1, x1m2, x2m1, x2m2, mask; union _doubleu x1, x2, result; x1.d = a1; x2.d = a2; exponent = x1.ieee.exponent - x2.ieee.exponent + EXCESSD; sign = x1.ieee.sign ^ x2.ieee.sign; x2.ieee.sign = 0; /* don't want the sign bit to affect any zero */ /* comparisons when checking for zero divide */ if (!x2.l.lower && !x2.l.upper) { /* check for zero divide */ result.l.lower = 0x0; if (sign) result.l.upper = 0xFFF00000; /* negative infinity */ else result.l.upper = 0x7FF00000; /* positive infinity */ return result.d; } if (!x1.l.upper && !x1.l.lower) /* check for 0.0 numerator */ return (0.0); x1m1 = x1.ieee.mantissa1 | D_PHANTOM_BIT; /* turn on phantom bit */ x1m2 = x1.ieee.mantissa2; x2m1 = x2.ieee.mantissa1 | D_PHANTOM_BIT; /* turn on phantom bit */ x2m2 = x2.ieee.mantissa2; if (__dcmp(x1m1,x1m2,x2m1,x2m2) < 0) { /* if x1's mantissa is less than x2's shift it left one and decrement */ /* the exponent to accommodate the change in the mantissa */ x1m1 <<= 1; /* */ bit_bucket = x1m2 >> 31; /* Shift mantissa left one */ x1m1 |= bit_bucket; /* */ x1m2 <<= 1; /* */ exponent--; } mantissa1 = 0; mantissa2 = 0; /* Get the first part of the results mantissa using successive */ /* subtraction. */ mask = 0x00200000; while (mask) { if (__dcmp(x1m1,x1m2,x2m1,x2m2) >= 0) { /* subtract x2's mantissa from x1's */ mantissa1 |= mask; /* turn on a bit in the result */ if (x2m2 > x1m2) x1m1--; x1m2 -= x2m2; x1m1 -= x2m1; } x1m1 <<= 1; /* */ bit_bucket = x1m2 >> 31; /* Shift mantissa left one */ x1m1 |= bit_bucket; /* */ x1m2 <<= 1; /* */ mask >>= 1; } /* Get the second part of the results mantissa using successive */ /* subtraction. */ mask = 0x80000000; while (mask) { if (__dcmp(x1m1,x1m2,x2m1,x2m2) >= 0) { /* subtract x2's mantissa from x1's */ mantissa2 |= mask; /* turn on a bit in the result */ if (x2m2 > x1m2) x1m1--; x1m2 -= x2m2; x1m1 -= x2m1; } x1m1 <<= 1; /* */ bit_bucket = x1m2 >> 31; /* Shift mantissa left one */ x1m1 |= bit_bucket; /* */ x1m2 <<= 1; /* */ mask >>= 1; } /* round up by adding 1 to mantissa */ if (mantissa2 == 0xFFFFFFFF) { /* check for over flow */ /* spill if overflow */ mantissa2 = 0; mantissa1++; } else mantissa2++; exponent++; /* increment exponent (mantissa must be shifted right */ /* also) */ /* shift mantissa right one and assume a phantom bit (which really gives */ /* 53 bits of precision in the mantissa) */ mantissa2 >>= 1; bit_bucket = mantissa1 & 1; mantissa2 |= (bit_bucket << 31); mantissa1 >>= 1; /* put all the info into the result */ result.ieee.exponent = exponent; result.ieee.sign = sign; result.ieee.mantissa1 = mantissa1; result.ieee.mantissa2 = mantissa2; return result.d;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -