Changeset 31407 in project
 Timestamp:
 09/12/14 12:25:43 (5 years ago)
 File:

 1 edited
Legend:
 Unmodified
 Added
 Removed

release/4/numbers/trunk/numbersc.c
r31405 r31407 1336 1336 1337 1337 *scan_r = 0; /* Ensure trimming works. TODO: set length directly? */ 1338 C_bignum_destructive_trim(result); 1339 C_kontinue(k, result); /* Normalize unnecessary; we added to a bignum. */ 1338 C_kontinue(k, C_bignum_normalize(result)); 1340 1339 } 1341 1340 } … … 1437 1436 (*scan_r++) = (*scan_x++); 1438 1437 1439 C_bignum_destructive_trim(result); /* Last digit may be 0. */ 1440 C_kontinue(k, C_bignum_normalize(result)); /* Might've reduced to fixnum */ 1438 C_kontinue(k, C_bignum_normalize(result)); 1441 1439 } 1442 1440 … … 1565 1563 } 1566 1564 1567 /* Normalization of the bignum's representation: remove trailing zeroes. */ 1568 void C_ccall 1569 C_bignum_destructive_trim(C_word big) 1570 { 1571 C_word *start = C_bignum_digits(big); 1572 C_word *last_digit = start + C_bignum_size(big); 1573 C_word *scan = last_digit; 1574 1575 while ((start <= scan) && ((*scan) == 0)) 1576 ; 1577 scan += 1; 1578 1579 if (scan < last_digit) { 1580 C_word len = scan  start; 1581 /* Mutate vector size of internal bignum vector. */ 1582 C_block_header(C_internal_bignum(big)) = (C_STRING_TYPE  C_wordstobytes(len+1)); 1583 /* Set internal header. */ 1584 C_bignum_header(big) = (C_bignum_header(big) & C_BIGNUM_HEADER_SIGN_BIT)  len; 1585 } 1586 } 1587 1588 /* Actual normalization: return a fixnum if the value fits. */ 1565 /* Normalization: scan trailing zeroes, then return a fixnum if the 1566 * value fits, or trim the bignum's length. */ 1589 1567 C_word C_ccall 1590 1568 C_bignum_normalize(C_word big) 1591 1569 { 1592 switch (C_bignum_size(big)) { 1570 C_word *start = C_bignum_digits(big); 1571 C_word *last_digit = start + C_bignum_size(big)  1; 1572 C_word *scan = last_digit, length; 1573 1574 while (scan >= start && *scan == 0) 1575 scan; 1576 length = scan  start + 1; 1577 1578 switch (length) { 1593 1579 case 0: 1594 1580 return C_fix(0); 1595 1581 case 1: 1596 return C_fix(C_bignum_negativep(big) ? 1597 C_bignum_digits(big)[0] : 1598 C_bignum_digits(big)[0]); 1582 return C_fix(C_bignum_negativep(big) ? *start : *start); 1599 1583 case 2: 1600 if (C_bignum_negativep(big) && 1601 C_bignum_digits(big)[1] == 1 && C_bignum_digits(big)[0] == 0) 1584 if (C_bignum_negativep(big) && *scan == 1 && *start == 0) 1602 1585 return C_fix(C_MOST_NEGATIVE_FIXNUM); 1586 /* FALLTHROUGH */ 1603 1587 default: 1588 if (scan < last_digit) { 1589 /* Mutate vector size of internal bignum vector. */ 1590 C_block_header(C_internal_bignum(big)) = (C_STRING_TYPE  C_wordstobytes(length+1)); 1591 /* Set internal header. */ 1592 C_bignum_header(big) = (C_bignum_header(big) & C_BIGNUM_HEADER_SIGN_BIT)  length; 1593 } 1604 1594 return big; 1605 1595 } … … 1675 1665 *end_digit = bignum_digits_destructive_scale_up_with_carry(digits, end_digit, 1676 1666 C_unfix(fixy), 0); 1677 C_bignum_destructive_trim(new_big);1678 1667 C_kontinue(k, C_bignum_normalize(new_big)); 1679 1668 } … … 1816 1805 (*scan_r) += carry; 1817 1806 } 1818 C_bignum_destructive_trim(result);1819 1807 C_kontinue(k, C_bignum_normalize(result)); 1820 1808 } … … 1901 1889 if (carry) (*last_digit++) = carry; /* Move end */ 1902 1890 1903 C_bignum_destructive_trim(result);1904 1891 C_kontinue(k, C_bignum_normalize(result)); 1905 1892 } … … 2058 2045 (*scan) = 0; 2059 2046 2060 C_bignum_destructive_trim(result);2061 2047 C_kontinue(k, C_bignum_normalize(result)); 2062 2048 } … … 2215 2201 *scanr = (*scanx++ & C_BIGNUM_DIGIT_MASK) >> bit_offset; 2216 2202 } 2217 C_bignum_destructive_trim(result);2218 2203 C_kontinue(k, C_bignum_normalize(result)); 2219 2204 } … … 2306 2291 *scan = ((double)rand())/(RAND_MAX + 1.0) * (double)((C_word)1 << C_BIGNUM_DIGIT_LENGTH); 2307 2292 2308 C_bignum_destructive_trim(result);2309 2293 C_kontinue(k, C_bignum_normalize(result)); 2310 2294 } … … 2375 2359 digit1 ^ digit2; 2376 2360 } 2377 C_bignum_destructive_trim(result);2378 2361 C_kontinue(k, C_bignum_normalize(result)); 2379 2362 } … … 2476 2459 } 2477 2460 } 2478 C_bignum_destructive_trim(result);2479 2461 C_kontinue(k, C_bignum_normalize(result)); 2480 2462 } … … 2540 2522 assert(C_fitsinbignumhalfdigitp(remainder)); 2541 2523 2542 C_bignum_destructive_trim(quotient);2543 2524 quotient = C_bignum_normalize(quotient); 2544 2525 … … 2584 2565 (*scan) = qj; 2585 2566 } 2586 C_bignum_destructive_trim(quotient);2587 2567 quotient = C_bignum_normalize(quotient); 2588 2568 } else {
Note: See TracChangeset
for help on using the changeset viewer.