div big
#include "stdint.h"
typedef uint32_t BN_ULONG;
# define BN_BITS 64
# define BN_BYTES 4
# define BN_BITS2 32
# define BN_BITS4 16
# define BN_MASK2 (0xffffffffL)
# define BN_MASK2l (0xffff)
# define BN_MASK2h1 (0xffff8000L)
# define BN_MASK2h (0xffff0000L)
# define BN_TBIT (0x80000000L)
# define BN_DEC_CONV (1000000000L)
#define THIRTY_TWO_BIT 1
int BN_num_bits_word(BN_ULONG l)
{
static const unsigned char bits[256] = {
0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
};
#if defined(SIXTY_FOUR_BIT_LONG)
if (l & 0xffffffff00000000L) {
if (l & 0xffff000000000000L) {
if (l & 0xff00000000000000L) {
return (bits[(int)(l >> 56)] + 56);
} else
return (bits[(int)(l >> 48)] + 48);
} else {
if (l & 0x0000ff0000000000L) {
return (bits[(int)(l >> 40)] + 40);
} else
return (bits[(int)(l >> 32)] + 32);
}
} else
#else
# ifdef SIXTY_FOUR_BIT
if (l & 0xffffffff00000000LL) {
if (l & 0xffff000000000000LL) {
if (l & 0xff00000000000000LL) {
return (bits[(int)(l >> 56)] + 56);
} else
return (bits[(int)(l >> 48)] + 48);
} else {
if (l & 0x0000ff0000000000LL) {
return (bits[(int)(l >> 40)] + 40);
} else
return (bits[(int)(l >> 32)] + 32);
}
} else
# endif
#endif
{
#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
if (l & 0xffff0000L) {
if (l & 0xff000000L)
return (bits[(int)(l >> 24L)] + 24);
else
return (bits[(int)(l >> 16L)] + 16);
} else
#endif
{
#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
if (l & 0xff00L)
return (bits[(int)(l >> 8)] + 8);
else
#endif
return (bits[(int)(l)]);
}
}
}
BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
{
BN_ULONG dh, dl, q, ret = 0, th, tl, t;
int i, count = 2;
if (d == 0)
return (BN_MASK2);
i = BN_num_bits_word(d);
// assert((i == BN_BITS2) || (h <= (BN_ULONG)1 << i));
i = BN_BITS2 - i;
if (h >= d)
h -= d;
if (i) {
d <<= i;
h = (h << i) | (l >> (BN_BITS2 - i));
l <<= i;
}
dh = (d & BN_MASK2h) >> BN_BITS4;
dl = (d & BN_MASK2l);
for (;;) {
if ((h >> BN_BITS4) == dh)
q = BN_MASK2l;
else
q = h / dh;
th = q * dh;
tl = dl * q;
for (;;) {
t = h - th;
if ((t & BN_MASK2h) ||
((tl) <= ((t << BN_BITS4) | ((l & BN_MASK2h) >> BN_BITS4))))
break;
q--;
th -= dh;
tl -= dl;
}
t = (tl >> BN_BITS4);
tl = (tl << BN_BITS4) & BN_MASK2h;
th += t;
if (l < tl)
th++;
l -= tl;
if (h < th) {
h += d;
q--;
}
h -= th;
if (--count == 0)
break;
ret = q << BN_BITS4;
h = ((h << BN_BITS4) | (l >> BN_BITS4)) & BN_MASK2;
l = (l & BN_MASK2l) << BN_BITS4;
}
ret |= q;
return (ret);
}
int cmain(int argc, char *argv[])
{
uint64_t a = 0xfff0000fffee9ull;
uint32_t ah = a >> 32;
uint32_t al = a;
uint32_t b = 0x1033245full;
auto r1 = bn_div_words(ah, al, b);
auto r2 = a / b;
return 0;
}
int main(int argc, char *argv[])
{
uint64_t a = 0xf0000001ull << 1;
uint32_t ah = a >> 32;
uint32_t al = a;
uint32_t b = 0xf0000001;
auto r1 = bn_div_words(ah, al, b);
return 0;
}