The old implementation of MP_FROMINT was grievously broken, it turns
out. Handle positive and negative numbers separately.
MP_DEST(_d, _sz, 0); \
_d->f &= ~(MP_NEG | MP_UNDEF); \
\
MP_DEST(_d, _sz, 0); \
_d->f &= ~(MP_NEG | MP_UNDEF); \
\
- /* --- Set the sign on the MP --- * \
- * \
- * If the input integer is *not* negative, then negate it. This \
- * fixes a problem with two's complement machines where the most \
- * negative value actually has larger magnitude than the most \
- * positive, and hence -TYPE_MIN == TYPE_MIN but TYPE_MIN != 0. If \
- * all the work is carried out on negative numbers there isn't a \
- * problem. \
- */ \
- \
- if (_i >= 0) \
- _i = -_i; \
- else \
+ if (_i >= 0) { \
+ while (_i) { \
+ if (_o == _sz) { \
+ _sz <<= 1; \
+ MP_ENSURE(_d, _sz); \
+ } \
+ _d->v[_o++] = MPW(_i); \
+ if (_i < MPW_MAX) \
+ break; \
+ else \
+ _i /= (type)MPW_MAX + 1; \
+ } \
+ } else { \
- \
- while (_i) { \
- if (_o == _sz) { \
- _sz <<= 1; \
- MP_ENSURE(_d, _sz); \
+ while (_i) { \
+ if (_o == _sz) { \
+ _sz <<= 1; \
+ MP_ENSURE(_d, _sz); \
+ } \
+ _d->v[_o++] = MPW(-_i); \
+ if (_i > -MPW_MAX) \
+ break; \
+ else \
+ _i /= (type)MPW_MAX + 1; \
- _d->v[_o++] = MPW(-_i); \
- \
- /* --- More subtlety --- * \
- * \
- * Ideally, I'd like to just shift @i@ right by @MPW_BITS@. But I \
- * can't, because that might be more than I'm allowed. I can't \
- * divide by @MPW_MAX + 1@ because that might turn out to be zero \
- * in my current type, and besides which it's unsigned which messes \
- * up all of my negative arithmetic. So do an explicit test here. \
- */ \
- \
- if (_i >= -MPW_MAX) \
- break; \
- else \
- _i /= (type)MPW_MAX + 1; \
_d->vl = _d->v + _o; \
(d) = _d; \
} while (0)
_d->vl = _d->v + _o; \
(d) = _d; \
} while (0)
+ 0x7ffff 0x7ffff;
+ 0x80000 0x80000;
+ 0xfffff 0xfffff;
0x7fffffff 0x7fffffff;
0x80000000 0x80000000; # Bastard torture test
0xffffffff 0xffffffff;
0x7fffffff 0x7fffffff;
0x80000000 0x80000000; # Bastard torture test
0xffffffff 0xffffffff;
+ 0x7ffff 0x7ffff;
+ 0x80000 0x80000;
+ 0xfffff 0xfffff;
0x7fffffff 0x7fffffff;
-0x80000000 -0x80000000; # Bastard torture test
}
0x7fffffff 0x7fffffff;
-0x80000000 -0x80000000; # Bastard torture test
}
+ 0x7ffff 0x7ffff;
+ 0x80000 0x80000;
+ 0xfffff 0xfffff;
0x7fffffff 0x7fffffff;
0x80000000 -0x80000000; # Bastard torture test
0xffffffff 0xffffffff;
0x7fffffff 0x7fffffff;
0x80000000 -0x80000000; # Bastard torture test
0xffffffff 0xffffffff;
+ 0x7ffff 0x7ffff;
+ 0x80000 0x80000;
+ 0xfffff 0xfffff;
0x7fffffff 0x7fffffff;
-0x80000000 -0x80000000; # Bastard torture test
}
0x7fffffff 0x7fffffff;
-0x80000000 -0x80000000; # Bastard torture test
}