shithub: femtolisp

Download patch

ref: 49717af9002a3be1f535799fb1804c42eeb4d187
parent: a4bfa20884163ae4a256c48da9eeac47a8fd4402
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Thu Nov 14 00:31:50 EST 2024

mp: fix mpbits with negative n

--- a/3rd/mp/mpaux.c
+++ b/3rd/mp/mpaux.c
@@ -47,7 +47,7 @@
 	mpint *b;
 
 	if(n < 0)
-		sysfatal("mpsetminbits: n < 0");
+		sysfatal("mpnew: n < 0");
 
 	n = DIGITS(n);
 	if(n < mpmindigits)
@@ -63,9 +63,9 @@
 	return b;
 }
 
-// guarantee at least n significant bits
+// guarantee at least m significant bits
 void
-mpbits(mpint *b, uint32_t m)
+mpbits(mpint *b, int m)
 {
 	uint32_t n;
 
--- a/posix/mp.h
+++ b/posix/mp.h
@@ -20,7 +20,7 @@
 #define sysfatal(s) do{ fprintf(stderr, "%s\n", s); abort(); }while(0)
 
 #define mpdighi  (mpdigit)(1U<<(Dbits-1))
-#define DIGITS(x) ((Dbits - 1 + (x))/Dbits)
+#define DIGITS(x) ((x) >= -(Dbits-1) ? ((Dbits - 1 + (x))/Dbits) : 0)
 
 // for converting between int's and mpint's
 #define MAXUINT ((uint32_t)-1)
@@ -68,7 +68,7 @@
 void	mpsetminbits(int n);	/* newly created mpint's get at least n bits */
 mpint*	mpnew(int n);		/* create a new mpint with at least n bits */
 void	mpfree(mpint *b);
-void	mpbits(mpint *b, uint32_t n);	/* ensure that b has at least n bits */
+void	mpbits(mpint *b, int n);	/* ensure that b has at least n bits */
 mpint*	mpnorm(mpint *b);		/* dump leading zeros */
 mpint*	mpcopy(mpint *b);
 void	mpassign(mpint *old, mpint *new);
--- a/test/unittest.lsp
+++ b/test/unittest.lsp
@@ -84,6 +84,8 @@
 
 (assert (fixnum? (- (aref "0" 0) #\0)))
 
+(assert (= (ash #bignum(1) -9999) 0))
+
 ; number boundaries
 (load "number-boundaries.lsp")