added the missing zero check in stix_divint()
This commit is contained in:
		| @ -288,6 +288,16 @@ PROCESS TESTING | ||||
| (-270000000000000000000000000000000000000000000000000000000000000000000 // 50000000000000000000000000000000000000000000000000000000000000000000) dump. | ||||
|  | ||||
|  | ||||
| ##(-270000000000000000000000000000000000000000000000000000000000000000000 rem: 5) dump. | ||||
| ##(-270000000000000000000000000000000000000000000000000000000000000000000 quo: 5) dump. | ||||
| ##(-270000000000000000000000000000000000000000000000000000000000000000000 \\ 5) dump. | ||||
| ##(-270000000000000000000000000000000000000000000000000000000000000000000 // 5) dump. | ||||
|  | ||||
| ##(-270 rem: 5) dump. | ||||
| ##(-270 quo: 5) dump. | ||||
| ##(-270 \\ 5) dump. | ||||
| ##(-270 // 5) dump. | ||||
|  | ||||
| " | ||||
| 		FFI isNil dump. | ||||
| 		FFI notNil dump. | ||||
|  | ||||
| @ -777,7 +777,7 @@ static stix_oop_t divide_unsigned_integers (stix_t* stix, stix_oop_t x, stix_oop | ||||
| 		((stix_oop_liword_t)y)->slot, STIX_OBJ_GET_SIZE(y), | ||||
| 		((stix_oop_liword_t)qq)->slot, ((stix_oop_liword_t)rr)->slot); | ||||
|  | ||||
| 	if (r) *r = rr; | ||||
| 	*r = rr; | ||||
| 	return qq; | ||||
| } | ||||
|  | ||||
| @ -1106,7 +1106,7 @@ oops_einval: | ||||
|  | ||||
| stix_oop_t stix_divints (stix_t* stix, stix_oop_t x, stix_oop_t y, int modulo, stix_oop_t* rem) | ||||
| { | ||||
| 	stix_oop_t z; | ||||
| 	stix_oop_t z, r; | ||||
| 	int x_neg, y_neg; | ||||
|  | ||||
| 	if (STIX_OOP_IS_SMOOI(x) && STIX_OOP_IS_SMOOI(y)) | ||||
| @ -1131,7 +1131,7 @@ stix_oop_t stix_divints (stix_t* stix, stix_oop_t x, stix_oop_t y, int modulo, s | ||||
| 		 *   mathematical relationship (all variables are integers): | ||||
| 		 *      a/b = q with remainder r | ||||
| 		 *   such that | ||||
| 		 *      b*q + r = a and 0 <= r < b (assuming a and b are >= 0). | ||||
| 		 *      b*q + r = a and 0 <= r < b (assuming- a and b are >= 0). | ||||
| 		 *  | ||||
| 		 *   If you want the relationship to extend for negative a | ||||
| 		 *   (keeping b positive), you have two choices: if you truncate q | ||||
| @ -1144,6 +1144,8 @@ stix_oop_t stix_divints (stix_t* stix, stix_oop_t x, stix_oop_t y, int modulo, s | ||||
| 		STIX_ASSERT (STIX_IN_SMOOI_RANGE(q)); | ||||
|  | ||||
| 		r = xv - yv * q; /* xv % yv; */ | ||||
| 		if (r) | ||||
| 		{ | ||||
| 			if (modulo) | ||||
| 			{ | ||||
| 				/* modulo */ | ||||
| @ -1187,6 +1189,7 @@ stix_oop_t stix_divints (stix_t* stix, stix_oop_t x, stix_oop_t y, int modulo, s | ||||
| 					STIX_ASSERT (xv && ((xv ^ r) >= 0)); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if (rem) | ||||
| 		{ | ||||
| @ -1256,86 +1259,64 @@ DO SHIFTING. | ||||
|  | ||||
| 	stix_pushtmp (stix, &x); | ||||
| 	stix_pushtmp (stix, &y); | ||||
| 	z = divide_unsigned_integers (stix, x, y, rem); | ||||
| 	z = divide_unsigned_integers (stix, x, y, &r); | ||||
| 	stix_poptmps (stix, 2); | ||||
| 	if (!z) return STIX_NULL; | ||||
| 	if (x_neg != y_neg)  | ||||
| 	{ | ||||
| 		STIX_OBJ_SET_CLASS(z, stix->_large_negative_integer); | ||||
| 	} | ||||
|  | ||||
| { int i; | ||||
| printf ("QUO=>"); | ||||
| for (i = STIX_OBJ_GET_SIZE(z); i > 0;) | ||||
| { | ||||
| printf ("%0*lX ", (int)(STIX_SIZEOF(stix_liw_t) * 2), (unsigned long)((stix_oop_liword_t)z)->slot[--i]); | ||||
| } | ||||
| printf ("\n"); | ||||
| } | ||||
|  | ||||
| /* TODO: handle modulo... */ | ||||
| 	if (rem) | ||||
| 	{ | ||||
| 		stix_pushtmp (stix, &z); | ||||
| 		*rem = normalize_bigint (stix, *rem); | ||||
| 		stix_poptmp (stix); | ||||
| 		if (!*rem) return STIX_NULL; | ||||
| 	if (x_neg != y_neg) STIX_OBJ_SET_CLASS(z, stix->_large_negative_integer); | ||||
|  | ||||
| 	if (x_neg)  | ||||
| 	{ | ||||
| 			STIX_OBJ_SET_CLASS(*rem, stix->_large_negative_integer); | ||||
| 			if (modulo) | ||||
| 			{ | ||||
| { int i; | ||||
| printf ("REM=>"); | ||||
| for (i = STIX_OBJ_GET_SIZE(*rem); i > 0;) | ||||
| { | ||||
| printf ("%0*lX ", (int)(STIX_SIZEOF(stix_liw_t) * 2), (unsigned long)((stix_oop_liword_t)*rem)->slot[--i]); | ||||
| } | ||||
| printf ("\n"); | ||||
| } | ||||
| 		/* the class on r must be set before normalize_bigint()  | ||||
| 		 * because it can turn it to a small integer */ | ||||
| 		STIX_OBJ_SET_CLASS(r, stix->_large_negative_integer); | ||||
|  | ||||
| 		stix_pushtmp (stix, &z); | ||||
| 		stix_pushtmp (stix, &y); | ||||
| 				*rem = stix_addints (stix, *rem, y); | ||||
| 		r = normalize_bigint (stix, r); | ||||
| 		stix_poptmps (stix, 2); | ||||
| 				if (!*rem) return STIX_NULL; | ||||
| 		if (!r) return STIX_NULL; | ||||
|  | ||||
| { int i; | ||||
| printf ("REM=>"); | ||||
| for (i = STIX_OBJ_GET_SIZE(*rem); i > 0;) | ||||
| 		if (r != STIX_SMOOI_TO_OOP(0) && modulo) | ||||
| 		{ | ||||
| printf ("%0*lX ", (int)(STIX_SIZEOF(stix_liw_t) * 2), (unsigned long)((stix_oop_liword_t)*rem)->slot[--i]); | ||||
| } | ||||
| printf ("\n"); | ||||
| } | ||||
| 				stix_pushtmp (stix, rem); | ||||
| 			if (rem) | ||||
| 			{ | ||||
| 				stix_pushtmp (stix, &z); | ||||
| 				stix_pushtmp (stix, &y); | ||||
| 				r = stix_addints (stix, r, y); | ||||
| 				stix_poptmps (stix, 2); | ||||
| 				if (!r) return STIX_NULL; | ||||
|  | ||||
| 				stix_pushtmp (stix, &r); | ||||
| 				z = normalize_bigint (stix, z); | ||||
| 				stix_poptmp (stix); | ||||
| 				if (!z) return STIX_NULL; | ||||
|  | ||||
| 				stix_pushtmp (stix, rem); | ||||
| 				stix_pushtmp (stix, &r); | ||||
| 				z = stix_subints (stix, z, STIX_SMOOI_TO_OOP(1)); | ||||
| 				stix_poptmp (stix); | ||||
|  | ||||
| 				*rem = r; | ||||
| 				return z; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| { int i; | ||||
| printf ("REM=>"); | ||||
| for (i = STIX_OBJ_GET_SIZE(*rem); i > 0;) | ||||
| { | ||||
| printf ("%0*lX ", (int)(STIX_SIZEOF(stix_liw_t) * 2), (unsigned long)((stix_oop_liword_t)*rem)->slot[--i]); | ||||
| } | ||||
| printf ("\n"); | ||||
| } | ||||
|  | ||||
| 	} | ||||
| 	else if (modulo && x_neg) | ||||
| 			else | ||||
| 			{ | ||||
| 				/* remainder is not needed at all */ | ||||
| /* TODO: subtract 1 without normalization??? */ | ||||
| 				z = normalize_bigint (stix, z); | ||||
| 				if (!z) return STIX_NULL; | ||||
| 				return stix_subints (stix, z, STIX_SMOOI_TO_OOP(1)); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		stix_pushtmp (stix, &z); | ||||
| 		r = normalize_bigint (stix, r); | ||||
| 		stix_poptmp (stix); | ||||
| 		if (!r) return STIX_NULL; | ||||
| 	} | ||||
|  | ||||
| 	if (rem) *rem = r; | ||||
| 	return normalize_bigint (stix, z); | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -115,6 +115,24 @@ void print_object (stix_t* stix, stix_oop_t oop) | ||||
| 			printf ("$%.*s", (int)bcslen, bcs); | ||||
| 		} | ||||
| 	} | ||||
| 	else if (STIX_OBJ_GET_CLASS(oop) == stix->_large_negative_integer) | ||||
| 	{ | ||||
| 		stix_oow_t i; | ||||
| 		printf ("-16r"); | ||||
| 		for (i = STIX_OBJ_GET_SIZE(oop); i > 0;) | ||||
| 		{ | ||||
| 			printf ("%0*lX", (int)(STIX_SIZEOF(stix_liw_t) * 2), (unsigned long)((stix_oop_liword_t)oop)->slot[--i]); | ||||
| 		} | ||||
| 	} | ||||
| 	else if (STIX_OBJ_GET_CLASS(oop) == stix->_large_positive_integer) | ||||
| 	{ | ||||
| 		stix_oow_t i; | ||||
| 		printf ("16r"); | ||||
| 		for (i = STIX_OBJ_GET_SIZE(oop); i > 0;) | ||||
| 		{ | ||||
| 			printf ("%0*lX", (int)(STIX_SIZEOF(stix_liw_t) * 2), (unsigned long)((stix_oop_liword_t)oop)->slot[--i]); | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		stix_oop_class_t c; | ||||
|  | ||||
		Reference in New Issue
	
	Block a user