From 3485fc41bcb8b082815b7d5e48a080c1fcfbab38 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Tue, 4 Apr 2006 17:20:05 +0100 Subject: [PATCH] mpint: Fix misbehaviour on larger-than-mpw integer types. The old implementation of MP_FROMINT was grievously broken, it turns out. Handle positive and negative numbers separately. --- mpint.h | 57 ++++++++++++++++++++++++--------------------------------- tests/mpint | 12 ++++++++++++ 2 files changed, 36 insertions(+), 33 deletions(-) diff --git a/mpint.h b/mpint.h index 23378cd..e44c39e 100644 --- a/mpint.h +++ b/mpint.h @@ -63,42 +63,33 @@ 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 { \ _d->f |= MP_NEG; \ - \ - 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) diff --git a/tests/mpint b/tests/mpint index c4faa39..49157ba 100644 --- a/tests/mpint +++ b/tests/mpint @@ -9,6 +9,9 @@ fromuint { 0 0; 1 1; -5 0xfffffffb; + 0x7ffff 0x7ffff; + 0x80000 0x80000; + 0xfffff 0xfffff; 0x7fffffff 0x7fffffff; 0x80000000 0x80000000; # Bastard torture test 0xffffffff 0xffffffff; @@ -18,6 +21,9 @@ fromint { 0 0; 1 1; -5 -5; + 0x7ffff 0x7ffff; + 0x80000 0x80000; + 0xfffff 0xfffff; 0x7fffffff 0x7fffffff; -0x80000000 -0x80000000; # Bastard torture test } @@ -26,6 +32,9 @@ touint { 0 0; 1 1; -5 -5; + 0x7ffff 0x7ffff; + 0x80000 0x80000; + 0xfffff 0xfffff; 0x7fffffff 0x7fffffff; 0x80000000 -0x80000000; # Bastard torture test 0xffffffff 0xffffffff; @@ -35,6 +44,9 @@ toint { 0 0; 1 1; -5 -5; + 0x7ffff 0x7ffff; + 0x80000 0x80000; + 0xfffff 0xfffff; 0x7fffffff 0x7fffffff; -0x80000000 -0x80000000; # Bastard torture test } -- 2.11.0