📄 fsdiv.c
字号:
/*
** libgcc support for software floating point.
** Copyright (C) 1991 by Pipeline Associates, Inc. All rights reserved.
** Permission is granted to do *anything* you want with this file,
** commercial or otherwise, provided this message remains intact. So there!
** I would appreciate receiving any updates/patches/changes that anyone
** makes, and am willing to be the repository for said changes (am I
** making a big mistake?).
**
** Pat Wood
** Pipeline Associates, Inc.
** pipeline!phw@motown.com or
** sun!pipeline!phw or
** uunet!motown!pipeline!phw
*/
/*
** $Id: fsdiv.c 3513 2004-10-01 14:49:51Z vrokas $
*/
/* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */
#include <float.h>
union float_long
{
float f;
long l;
};
/* divide two floats */
float __fsdiv (float a1, float a2) _FS_REENTRANT
{
FS_STATIC volatile union float_long fl1, fl2;
long result;
unsigned long mask;
long mant1, mant2;
int exp ;
char sign;
fl1.f = a1;
fl2.f = a2;
/* subtract exponents */
exp = EXP (fl1.l) ;
exp -= EXP (fl2.l);
exp += EXCESS;
/* compute sign */
sign = SIGN (fl1.l) ^ SIGN (fl2.l);
/* divide by zero??? */
if (!fl2.l)
{/* return NaN or -NaN */
fl2.l = 0x7FC00000;
return (fl2.f);
}
/* numerator zero??? */
if (!fl1.l)
return (0);
/* now get mantissas */
mant1 = MANT (fl1.l);
mant2 = MANT (fl2.l);
/* this assures we have 25 bits of precision in the end */
if (mant1 < mant2)
{
mant1 <<= 1;
exp--;
}
/* now we perform repeated subtraction of fl2.l from fl1.l */
mask = 0x1000000;
result = 0;
while (mask)
{
if (mant1 >= mant2)
{
result |= mask;
mant1 -= mant2;
}
mant1 <<= 1;
mask >>= 1;
}
/* round */
result += 1;
/* normalize down */
exp++;
result >>= 1;
result &= ~HIDDEN;
/* pack up and go home */
if (exp >= 0x100)
fl1.l = (sign ? SIGNBIT : 0) | 0x7F800000;
else if (exp < 0)
fl1.l = 0;
else
fl1.l = PACK (sign ? SIGNBIT : 0 , exp, result);
return (fl1.f);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -