mirror of
https://github.com/autc04/Retro68.git
synced 2024-11-30 19:53:46 +00:00
135 lines
2.0 KiB
C
135 lines
2.0 KiB
C
|
|
||
|
#define divnorm(num, den, sign) \
|
||
|
{ \
|
||
|
if (num < 0) \
|
||
|
{ \
|
||
|
num = -num; \
|
||
|
sign = 1; \
|
||
|
} \
|
||
|
else \
|
||
|
{ \
|
||
|
sign = 0; \
|
||
|
} \
|
||
|
\
|
||
|
if (den < 0) \
|
||
|
{ \
|
||
|
den = - den; \
|
||
|
sign = 1 - sign; \
|
||
|
} \
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
static unsigned long
|
||
|
divmodsi4(int modwanted, unsigned long num, unsigned long den)
|
||
|
{
|
||
|
long int bit = 1;
|
||
|
long int res = 0;
|
||
|
long prevden;
|
||
|
while (den < num && bit && !(den & (1L<<31)))
|
||
|
{
|
||
|
den <<=1;
|
||
|
bit <<=1;
|
||
|
}
|
||
|
while (bit)
|
||
|
{
|
||
|
if (num >= den)
|
||
|
{
|
||
|
num -= den;
|
||
|
res |= bit;
|
||
|
}
|
||
|
bit >>=1;
|
||
|
den >>=1;
|
||
|
}
|
||
|
if (modwanted) return num;
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
|
||
|
#define exitdiv(sign, res) if (sign) { res = - res;} return res;
|
||
|
|
||
|
long
|
||
|
__modsi3 (long numerator, long denominator)
|
||
|
{
|
||
|
int sign = 0;
|
||
|
long dividend;
|
||
|
long modul;
|
||
|
|
||
|
|
||
|
if (numerator < 0)
|
||
|
{
|
||
|
numerator = -numerator;
|
||
|
sign = 1;
|
||
|
}
|
||
|
if (denominator < 0)
|
||
|
{
|
||
|
denominator = -denominator;
|
||
|
}
|
||
|
|
||
|
modul = divmodsi4 (1, numerator, denominator);
|
||
|
if (sign)
|
||
|
return - modul;
|
||
|
return modul;
|
||
|
}
|
||
|
|
||
|
|
||
|
long
|
||
|
__divsi3 (long numerator, long denominator)
|
||
|
{
|
||
|
int sign;
|
||
|
long dividend;
|
||
|
long modul;
|
||
|
divnorm (numerator, denominator, sign);
|
||
|
|
||
|
dividend = divmodsi4 (0, numerator, denominator);
|
||
|
exitdiv (sign, dividend);
|
||
|
}
|
||
|
|
||
|
long
|
||
|
__umodsi3 (unsigned long numerator, unsigned long denominator)
|
||
|
{
|
||
|
long dividend;
|
||
|
long modul;
|
||
|
|
||
|
modul= divmodsi4 (1, numerator, denominator);
|
||
|
return modul;
|
||
|
}
|
||
|
|
||
|
long
|
||
|
__udivsi3 (unsigned long numerator, unsigned long denominator)
|
||
|
{
|
||
|
int sign;
|
||
|
long dividend;
|
||
|
long modul;
|
||
|
dividend = divmodsi4 (0, numerator, denominator);
|
||
|
return dividend;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
#ifdef TEST
|
||
|
|
||
|
|
||
|
|
||
|
main ()
|
||
|
{
|
||
|
long int i, j, k, m;
|
||
|
for (i = -10000; i < 10000; i += 8)
|
||
|
{
|
||
|
for (j = -10000; j < 10000; j += 11)
|
||
|
{
|
||
|
k = i / j;
|
||
|
m = __divsi3 (i, j);
|
||
|
if (k != m)
|
||
|
printf ("fail %d %d %d %d\n", i, j, k, m);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif
|