rev 564 - in trunk: pr/test src

SVN User <[email protected]> Thu, 03 Jun 2004 01:06:14 -0400
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-06-03 01:06:11 -0400 (Thu, 03 Jun 2004)
New Revision: 564

Added:
   trunk/pr/test/int.pr
Modified:
   trunk/pr/test/test.pr
   trunk/src/builtins-int.c
Log:
fixed bug in ints, added int.pr

Added: trunk/pr/test/int.pr
===================================================================
--- trunk/pr/test/int.pr	2004-06-03 01:15:55 UTC (rev 563)
+++ trunk/pr/test/int.pr	2004-06-03 05:06:11 UTC (rev 564)
@@ -0,0 +1,43 @@
+#!/usr/bin/env prothon
+
+def err(n):
+	print 'error', n
+	Sys.exit(1)
+
+x = 1
+if x != 1: err(0)
+	
+for i in 200:
+	x *= 2
+
+y = 2**200
+
+if x != y: 
+	print 'x:',x
+	print 'y:',y
+	err(1)
+if x != 1606938044258990275541962092341162602522202993782792835301376:
+	err(2)
+
+for i in 200:
+	x //=2
+
+if x != 1: err(3)
+
+x = 254373265453637
+if -(823 * 2134 + 3184536 - 42312 % 311) | 19234567 & 149578376456 != -4915202:
+	err(4)
+
+if -(8211442569234385238487474353 * 212847346352034947352764 + 31842289378376456945234123236
+        - 44872283873746635434256223262312 % 3387611
+        ) | 192328437462345263464564567 & 1495728438374645645346368376456 != 
+				-1747783760583674902504339775785929746473575241492788:
+	err(5)
+
+y = 1002003004005006007008009000100200300400500600700800900
+print """
+--- All tests passed ---
+
+The following should match:
+1002003004005006007008009000100200300400500600700800900"""
+print y
\ No newline at end of file


Property changes on: trunk/pr/test/int.pr
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/pr/test/test.pr
===================================================================
--- trunk/pr/test/test.pr	2004-06-03 01:15:55 UTC (rev 563)
+++ trunk/pr/test/test.pr	2004-06-03 05:06:11 UTC (rev 564)
@@ -1,10 +1,9 @@
 #!/usr/bin/env prothon
 
-
 def err(n):
 	print 'error', n
 	Sys.exit(1)
-/*
+
 x = 1
 if x != 1: err(0)
 	
@@ -25,14 +24,15 @@
 
 if x != 1: err(3)
 
-
 x = 254373265453637
 if -(823 * 2134 + 3184536 - 42312 % 311) | 19234567 & 149578376456 != -4915202:
 	err(4)
-*/
-print -(8211442569234385238487474353 * 212847346352034947352764 + 31842289378376456945234123236
+
+if -(8211442569234385238487474353 * 212847346352034947352764 + 31842289378376456945234123236
         - 44872283873746635434256223262312 % 3387611
-        ) | 192328437462345263464564567 & 1495728438374645645346368376456 
+        ) | 192328437462345263464564567 & 1495728438374645645346368376456 != 
+				-1747783760583674902504339775785929746473575241492788:
+	err(5)
 
 y = 1002003004005006007008009000100200300400500600700800900
 print """

Modified: trunk/src/builtins-int.c
===================================================================
--- trunk/src/builtins-int.c	2004-06-03 01:15:55 UTC (rev 563)
+++ trunk/src/builtins-int.c	2004-06-03 05:06:11 UTC (rev 564)
@@ -141,8 +141,11 @@
 
 //********************************* new_int_long_obj **************************
 obj_p new_int_long_obj(isp ist, long_p longp){
-	int len        = sizeof(long_t) + abs(longp->dsize) * sizeof(digit);
-	obj_p obj      = NEW_OBJ(OBJ(INT_PROTO));
+	int len;
+	obj_p obj;
+	long_normalize(longp);
+	len            = sizeof(long_t) + abs(longp->dsize) * sizeof(digit);
+	obj            = NEW_OBJ(OBJ(INT_PROTO));
 	obj->data_type = DATA_TYPE_DATAPTR;
 	obj->data.ptr  = pr_malloc(len);
 	memcpy(obj->data.ptr, longp, len);
@@ -182,18 +185,17 @@
 	return longp;
 }
 
-long_p copy_longp(long_p src) {
+long_p copy_longp(long_p src, int size_padding) {
 	long_p result;
 	int i;
-	assert(src != NULL);
-	i = abs(src->dsize)+1;
+	pr_assert(src != NULL);
+	i = abs(src->dsize) + size_padding;
 	result = new_longp_non_init(i);
 	if (result != NULL) {
-		if (src->dsize >= 0) result->dsize =  i; 
-		else                 result->dsize = -i; 
-		result->digit[--i] = 0;
+		if (src->dsize >= 0) result->dsize =  i;
+		else                 result->dsize = -i;
 		while (--i >= 0)
-			result->digit[i] = src->digit[i];
+			result->digit[i] = (i >= abs(src->dsize) ? 0 : src->digit[i]);
 	}
 	return (long_p)result;
 }
@@ -310,9 +312,9 @@
 	size_t result = 0;
 	int ndigits;
 
-	assert(v != NULL);
+	pr_assert(v != NULL);
 	ndigits = abs(v->dsize);
-	assert(ndigits == 0 || v->digit[ndigits - 1] != 0);
+	pr_assert(ndigits == 0 || v->digit[ndigits - 1] != 0);
 	if (ndigits > 0) {
 		digit msd = v->digit[ndigits - 1];
 
@@ -377,7 +379,7 @@
 	/* There are i digits we didn't shift in. Pretending they're all
 	  zeroes, the true value is x * 2**(i*SHIFT). */
 	*exponent = i;
-	assert(x > 0.0);
+	pr_assert(x > 0.0);
 	return x * sign;
 #undef NBITS_WANTED
 }
@@ -407,7 +409,7 @@
 }
 
 
-#define CONVERT_BINOP(v, w, a, b) *a = long_normalize(v); *b = long_normalize(w);
+#define CONVERT_BINOP(v, w, a, b) *a = copy_longp(long_normalize(v), 0); *b = copy_longp(long_normalize(w), 0);
 
 /* x[0:m] and y[0:n] are digit vectors, LSD first, m >= n required. x[0:n]
  * is modified in place, by adding y to it. Carries are propagated as far as
@@ -417,18 +419,18 @@
 	int i;
 	digit carry = 0;
 
-	assert(m >= n);
+	pr_assert(m >= n);
 	for (i = 0; i < n; ++i) {
 		carry += x[i] + y[i];
 		x[i] = carry & MASK;
 		carry >>= SHIFT;
-		assert((carry & 1) == carry);
+		pr_assert((carry & 1) == carry);
 	}
 	for (; carry && i < m; ++i) {
 		carry += x[i];
 		x[i] = carry & MASK;
 		carry >>= SHIFT;
-		assert((carry & 1) == carry);
+		pr_assert((carry & 1) == carry);
 	}
 	return carry;
 }
@@ -442,7 +444,7 @@
 	int i;
 	digit borrow = 0;
 
-	assert(m >= n);
+	pr_assert(m >= n);
 	for (i = 0; i < n; ++i) {
 		borrow = x[i] - y[i] - borrow;
 		x[i] = borrow & MASK;
@@ -495,7 +497,7 @@
 {
 	twodigits rem = 0;
 
-	assert(n > 0 && n <= MASK);
+	pr_assert(n > 0 && n <= MASK);
 	pin += dsize;
 	pout += dsize;
 	while (--dsize >= 0) {
@@ -516,7 +518,7 @@
 	const int dsize = abs(a->dsize);
 	long_p z;
 
-	assert(n > 0 && n <= MASK);
+	pr_assert(n > 0 && n <= MASK);
 	z = new_longp_non_init(dsize);
 	if (z == NULL)
 		return NULL;
@@ -536,7 +538,7 @@
 	int bits;
 	char sign = '\0';
 
-	assert(base >= 2 && base <= 36);
+	pr_assert(base >= 2 && base <= 36);
 
 	/* Compute a rough upper bound for the length of the string */
 	i = base;
@@ -570,11 +572,11 @@
 		for (i = 0; i < size_a; ++i) {
 			accum |= (twodigits)a->digit[i] << accumbits;
 			accumbits += SHIFT;
-			assert(accumbits >= basebits);
+			pr_assert(accumbits >= basebits);
 			do {
 				char cdigit = (char)(accum & (base - 1));
 				cdigit += (cdigit < 10) ? '0' : 'A'-10;
-				assert(p > pr_strptr(str));
+				pr_assert(p > pr_strptr(str));
 				*--p = cdigit;
 				accumbits -= basebits;
 				accum >>= basebits;
@@ -622,11 +624,11 @@
 			})
 
 			/* Break rem into digits. */
-			assert(ntostore > 0);
+			pr_assert(ntostore > 0);
 			do {
 				digit nextrem = (digit)(rem / base);
 				char c = (char)(rem - nextrem * base);
-				assert(p > pr_strptr(str));
+				pr_assert(p > pr_strptr(str));
 				c += (c < 10) ? '0' : 'A'-10;
 				*--p = c;
 				rem = nextrem;
@@ -657,7 +659,7 @@
 		*--p = sign;
 	if (p != pr_strptr(str)) {
 		char *q = pr_strptr(str);
-		assert(p > q);
+		pr_assert(p > q);
 		do {
 		} while ((*q++ = *p++) != '\0');
 	}
@@ -680,7 +682,7 @@
 	int bits_in_accum;
 	digit *pdigit;
 
-	assert(base >= 2 && base <= 32 && (base & (base - 1)) == 0);
+	pr_assert(base >= 2 && base <= 32 && (base & (base - 1)) == 0);
 	n = base;
 	for (bits_per_char = -1; n; ++bits_per_char)
 		n >>= 1;
@@ -727,24 +729,24 @@
 		else if (ch >= 'a')
 			k = ch - 'a' + 10;
 		else {
-			assert(ch >= 'A');
+			pr_assert(ch >= 'A');
 			k = ch - 'A' + 10;
 		}
-		assert(k >= 0 && k < base);
+		pr_assert(k >= 0 && k < base);
 		accum |= (twodigits)(k << bits_in_accum);
 		bits_in_accum += bits_per_char;
 		if (bits_in_accum >= SHIFT) {
 			*pdigit++ = (digit)(accum & MASK);
-			assert(pdigit - z->digit <= n);
+			pr_assert(pdigit - z->digit <= n);
 			accum >>= SHIFT;
 			bits_in_accum -= SHIFT;
-			assert(bits_in_accum < SHIFT);
+			pr_assert(bits_in_accum < SHIFT);
 		}
 	}
 	if (bits_in_accum) {
-		assert(bits_in_accum <= SHIFT);
+		pr_assert(bits_in_accum <= SHIFT);
 		*pdigit++ = (digit)accum;
-		assert(pdigit - z->digit <= n);
+		pr_assert(pdigit - z->digit <= n);
 	}
 	while (pdigit - z->digit < n)
 		*pdigit++ = 0;
@@ -855,9 +857,7 @@
 
 /* Long division with remainder, top-level routine */
 
-static int long_divrem(long_p a, long_p b,
-	  long_p *pdiv, long_p *prem)
-{
+static int long_divrem(long_p a, long_p b, long_p *pdiv, long_p *prem) {
 	int size_a = abs(a->dsize), size_b = abs(b->dsize);
 	long_p z;
 
@@ -872,7 +872,7 @@
 		/* |a| < |b|. */
 		*pdiv = new_longp_non_init(0);
 		Py_INCREF(a);
-		*prem = (long_p) a;
+		*prem = copy_longp(a, 0);
 		return 0;
 	}
 	if (size_b == 1) {
@@ -916,8 +916,8 @@
 		return NULL;
 	}
 
-	assert(size_v >= size_w && size_w > 1); /* Assert checks by div() */
-	assert(size_w == abs(w->dsize)); /* That's how d was calculated */
+	pr_assert(size_v >= size_w && size_w > 1); /* Assert checks by div() */
+	pr_assert(size_w == abs(w->dsize)); /* That's how d was calculated */
 
 	size_v = abs(v->dsize);
 	a = new_longp_non_init(size_v - size_w + 1);
@@ -967,7 +967,7 @@
 		if (carry == 0)
 			a->digit[k] = (digit) q;
 		else {
-			assert(carry == -1);
+			pr_assert(carry == -1);
 			a->digit[k] = (digit) q-1;
 			carry = 0;
 			for (i = 0; i < size_w && i+k < size_v; ++i) {
@@ -1103,7 +1103,7 @@
 		borrow >>= SHIFT;
 		borrow &= 1; /* Keep only one sign bit */
 	}
-	assert(borrow == 0);
+	pr_assert(borrow == 0);
 	if (sign < 0)
 		z->dsize = -(z->dsize);
 	return long_normalize(z);
@@ -1187,7 +1187,7 @@
 			carry >>= SHIFT;
 		}
 		for (; carry != 0; ++j) {
-			assert(i+j < z->dsize);
+			pr_assert(i+j < z->dsize);
 			carry += *pz;
 			*pz++ = (digit) (carry & MASK);
 			carry >>= SHIFT;
@@ -1287,7 +1287,7 @@
 	/* Split a & b into hi & lo pieces. */
 	shift = bsize >> 1;
 	if (kmul_split(a, shift, &ah, &al) < 0) goto fail;
-	assert(ah->dsize > 0);	/* the split isn't degenerate */
+	pr_assert(ah->dsize > 0);	/* the split isn't degenerate */
 
 	if (kmul_split(b, shift, &bh, &bl) < 0) goto fail;
 
@@ -1317,8 +1317,8 @@
 
 	/* 2. t1 <- ah*bh, and copy into high digits of result. */
 	if ((t1 = k_mul(ah, bh)) == NULL) goto fail;
-	assert(t1->dsize >= 0);
-	assert(2*shift + t1->dsize <= ret->dsize);
+	pr_assert(t1->dsize >= 0);
+	pr_assert(2*shift + t1->dsize <= ret->dsize);
 	memcpy(ret->digit + 2*shift, t1->digit,
 	    t1->dsize * sizeof(digit));
 
@@ -1333,8 +1333,8 @@
 		pr_free(t1);
 		goto fail;
 	}
-	assert(t2->dsize >= 0);
-	assert(t2->dsize <= 2*shift); /* no overlap with high digits */
+	pr_assert(t2->dsize >= 0);
+	pr_assert(t2->dsize <= 2*shift); /* no overlap with high digits */
 	memcpy(ret->digit, t2->digit, t2->dsize * sizeof(digit));
 
 	/* Zero out remaining digits. */
@@ -1370,7 +1370,7 @@
 	pr_free(t1);
 	pr_free(t2);
 	if (t3 == NULL) goto fail;
-	assert(t3->dsize >= 0);
+	pr_assert(t3->dsize >= 0);
 
 	/* Add t3. It's not obvious why we can't run out of room here.
 	 * See the (*) comment after this function.
@@ -1450,8 +1450,8 @@
 	long_p ret;
 	long_p bslice = NULL;
 
-	assert(asize > KARATSUBA_CUTOFF);
-	assert(2 * asize <= bsize);
+	pr_assert(asize > KARATSUBA_CUTOFF);
+	pr_assert(2 * asize <= bsize);
 
 	/* Allocate result space, and zero it out. */
 	ret = new_longp_non_init(asize + bsize);
@@ -1496,7 +1496,7 @@
 }
 
 static long_p long_mul(long_p v, long_p w) {
-	long_p a=copy_longp(v), b=copy_longp(w), z;
+	long_p a = copy_longp(v, 1), b = copy_longp(w, 1), z;
 	
 	z = k_mul(a, b);
 	/* Negate if exactly one of the inputs is negative. */
@@ -1539,7 +1539,7 @@
 			pr_free(div);
 			return -1;
 		}
-		one = (long_p) new_longp(1L);
+		one = (long_p) new_longp(1);
 		if (one == NULL ||
 		  (temp = (long_p) long_sub(div, one)) == NULL) {
 			pr_free(mod);
@@ -1739,7 +1739,7 @@
 	/* Implement ~x as -(x+1) */
 	long_p x;
 	long_p w;
-	w = (long_p)new_longp(1L);
+	w = (long_p)new_longp(1);
 	if (w == NULL)
 		return NULL;
 	x = (long_p) long_add(v, w);
@@ -1857,7 +1857,7 @@
 	if (remshift)
 		z->digit[newsize-1] = (digit)accum;
 	else
-		assert(!accum);
+		pr_assert(!accum);
 	z = long_normalize(z);
 lshift_error:
 	pr_free(a);