[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Fixnum 1+ 1- fix



The patch I posted last time was the minimal-change fix.
Upon looking it over I realized that there's a much
cleaner way to do it that's clearer and faster than
the original code, whether it had a bug or not.

Simply, for (1+ i) if i is most-positive-fixnum,
then the result is the smallest positive bignum,
otherwise it's still a fixnum, likewise for (1- i)
and most-negative-fixnum.  The code doesn't depend
on machine arithmetic (as long as an int can hold
a fixnum), and is shorter and faster.

------- num_arith.c -------
412,432c412,419
< 		if(i == 0)
< 			return(small_fixnum(1));
< 		if(i > 0)
< 			if (++i > 0) {
< 				if (-SMALL_FIXNUM_LIMIT <= i &&
< 				    i < SMALL_FIXNUM_LIMIT)
< 					return(small_fixnum(i));
< 				z = alloc_object(t_fixnum);
< 				fix(z) = i;
< 				return(z);
< 			} else
< 				return(bignum2(1, i & MASK));
< 		else {
< 			i++;
< 			if (-SMALL_FIXNUM_LIMIT <= i &&
< 			    i < SMALL_FIXNUM_LIMIT)
< 				return(small_fixnum(i));
< 			z = alloc_object(t_fixnum);
< 			fix(z) = i;
< 			return(z);
< 		}
---
> 		if (i == MOST_POSITIVE_FIX)
> 			return(bignum2(1, 0));
> 		i++;
> 		if (-SMALL_FIXNUM_LIMIT <= i && i < SMALL_FIXNUM_LIMIT)
> 			return(small_fixnum(i));
> 		z = alloc_object(t_fixnum);
> 		fix(z) = i;
> 		return(z);
691,710c678,685
< 		if(i == 0)
< 			return(small_fixnum(-1));
< 		if(i > 0) {
< 			i--;
< 			if (-SMALL_FIXNUM_LIMIT <= i &&
< 			    i < SMALL_FIXNUM_LIMIT)
< 				return(small_fixnum(i));
< 			z = alloc_object(t_fixnum);
< 			fix(z) = i;
< 			return(z);
< 		} else
< 			if (--i < 0) {
< 				if (-SMALL_FIXNUM_LIMIT <= i &&
< 				    i < SMALL_FIXNUM_LIMIT)
< 					return(small_fixnum(i));
< 				z = alloc_object(t_fixnum);
< 				fix(z) = i;
< 				return(z);
< 			} else
< 				return(bignum2(-2, i & MASK));
---
> 		if (i == MOST_NEGATIVE_FIX)
> 			return(bignum2(-2, MOST_POSITIVE_FIX));
> 		i--;
> 		if (-SMALL_FIXNUM_LIMIT <= i && i < SMALL_FIXNUM_LIMIT)
> 			return(small_fixnum(i));
> 		z = alloc_object(t_fixnum);
> 		fix(z) = i;
> 		return(z);