Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Intreg arrmultiply(Intreg termA[], Intreg termB[], Intreg lenA, Intreg lenB, Intreg base)
- {
- /* Find sign, if any. (1 for +, -1 for -, 0 for not found.) */
- Intreg signA <- find_sign(termA)
- Intreg signB <- find_sign(termB)
- // Skip sign OR set sign to 1 if no sign was found.
- Intreg termA_1st_digit, termB_1st_digit
- termA_1st_digit <- termB_1st_digit <- 0
- daca (signA) {
- termA_1st_digit++
- }
- altfel {
- signA <- 1
- }
- daca (signB) {
- termB_1st_digit++
- }
- altfel {
- signB <- 1
- }
- /* 0 * ... */
- daca ((lenA - termA_1st_digit) = 1 AND termA[termA_1st_digit] = 0) {
- termB[0] <- 0
- returneaza 1
- }
- /* ... * 0 */
- daca ((lenB - termB_1st_digit) = 1 AND termB[termB_1st_digit] = 0) {
- termB[0] <- 0
- returneaza 1
- }
- /* Get result sign. */
- Intreg result_sign <- signA * signB
- multiplicand:Interg[lenA + lenB + 1]
- multiplier:Intreg[MAX(lenA, lenB]
- Intreg lenM, lenm
- /* Copy the "shorter" number into multiplier (for less shifts of the multiplicand). */
- daca (lenA > lenB OR lenA = lenB) {
- lenM <- arrncpy(multiplicand, termA, lenA, termA_1st_digit, (lenA - 1) - termA_1st_digit)
- lenm <- arrncpy(multiplier, termB, lenB, termB_1st_digit, (lenB - 1) - termB_1st_digit)
- }
- altfel daca (lenB > lenA) {
- lenM <- arrncpy(multiplicand, termB, lenB, termB_1st_digit, (lenB - 1) - termB_1st_digit)
- lenm <- arrncpy(multiplier, termA, lenA, termA_1st_digit, (lenA - 1) - termA_1st_digit)
- }
- /* Make the result (termB) 0. */
- Intreg result_len
- result_len <- lenA + lenB + 1
- pentru i=0,result_len-1,1 {
- termB[i] <- 0
- }
- Intreg jRes
- jRes <- result_len - 1
- Intreg sum, transport
- transport <- 0
- pentru i=lenm-1,0,-1 {
- prentru j=lenM-1,0,-1 {
- /* Multiply and do the sum. */
- sum <- (multiplier[i] * multiplicand[j]) + termB[jRes] + transport
- /* Get the rest. */
- termB[jRes] <- (sum % base)
- /* Get the transport. */
- transport <- (sum - termB[jRes]) / base
- jRes--
- }
- daca (transport) {
- termB[jRes] <- transport
- transport <- 0
- }
- jRes <- result_len - 1
- /* abc -> abc0 -> abc00 -> abc000 -> ...*/
- lenM <- arrnshift(multiplicand, lenM, lenM, 1)
- }
- /* Count the number of insegnificant zeors. */
- int offset <- 0
- while (offset < result_len AND !termB[offset]) {
- offset++
- }
- /* Set sign. */
- daca (result_sign <-= -1) {
- termB[0] <- '-'
- termB_1st_digit <- 1
- offset--
- }
- altfel {
- termB_1st_digit <- 0
- }
- /* Delete insegnificant zeros, if any. */
- lenB <- arrnshift(termB, result_len, termB_1st_digit, -offset)
- returneaza lenB
- }
- Intreg arrsub(Intreg termA[], Intreg termB[], Intreg lenA, Intreg lenB, Intreg base)
- {
- /* Find sign, if any. (1 for +, -1 for -, 0 for not found.) */
- Intreg signA <- find_sign(termA)
- Intreg signB <- find_sign(termB)
- // Skip sign OR set sign to 1 if no sign was found.
- Intreg termA_1st_digit, termB_1st_digit
- termA_1st_digit <- termB_1st_digit <- 0
- daca (signA) {
- termA_1st_digit++
- }
- altfel {
- signA <- 1
- }
- daca (signB) {
- termB_1st_digit++
- }
- altfel {
- signB <- 1
- }
- /* Find the order relation between termA and termB. */
- Intreg order <- arrnumber_cmp(termA, termB, lenA, lenB)
- // -a - b = - (a + b) a - -b = a + b
- daca ( (signA = -1) AND (signB = 1) ) OR ( (signA = 1) AND (signB = -1) ) {
- daca (signA = -1) {
- daca (termB_1st_digit = 0) {
- lenB <- arrnshift(termB, lenB, termB_1st_digit, 1)
- }
- termB[0] <- '-'
- }
- altfel {
- arrnshift(termB, lenB, 0, -1)
- lenB--
- }
- return arradd(termA, termB, lenA, lenB, base)
- }
- // -a - (-b) = -a + b
- altfel daca (signB = -1) {
- signB <- 1
- }
- // The remaining calculation: a - b = a + (-b)
- altfel {
- signB <- -1
- }
- /* So there's either (-a + b) OR (a + (-b)) to calculate */
- /*[Obs] The next statemates make sure that the smaller number is the negative number
- * and if any signs are changed, set result_sign accordingly.
- */
- Intreg result_sign <- 0
- /* Subbing numbers equal in module => 0. */
- daca (!order) {
- termB[0] <- 0
- return 1
- }
- /*If a > b AND -a + b to calculate; then flip signs: a + (-b). */
- altfel daca (order > 0 AND (signA = -1)) {
- result_sign <- signA // Set result_sign <- sign of the greater number (a > b).
- signA <- 1
- signB <- -1
- }
- /*Elif a < b AND a + (-b) to calculate; then flip signs: -a + b */
- altfel daca (order < 0 AND (signB = -1)) {
- result_sign <- signB // Set result_sign <- sign of the greater number (b > a).
- signA <- -1
- signB <- 1
- }
- /* If termB (which will store the result) is smaller than termA. */
- daca (
- (lenB - termB_1st_digit) < (lenA - termA_1st_digit)
- )
- {
- /* Shift termB, starting at the first digit. */
- lenB <- arrnshift(termB, lenB, termB_1st_digit, lenA - lenB)
- }
- /* Operate */
- Intreg iA, jB
- iA <- lenA - 1
- jB <- lenB - 1
- Intreg sum
- sum <- 0
- /* Right to left do signed addition. */
- cat timp (
- iA >= termA_1st_digit AND
- jB >= termB_1st_digit
- )
- {
- sum <- termA[iA] * signA + termB[jB] * signB
- daca (sum < 0) {
- // Borrow from the positive number.
- daca (signA = 1) {
- sum += arrborrow(termA, iA, base)
- }
- altfel {
- sum += arrborrow(termB, jB, base)
- }
- }
- termB[jB] <- sum
- iA-- jB--;
- }
- /* Count insegnificant zeros. */
- Intreg offset <- termB_1st_digit
- cat timp (offset < lenB AND !termB[offset]) {
- offset++
- }
- offset -= termB_1st_digit
- /* Delete insegnificant zeros, if any. */
- lenB <- arrnshift(termB, lenB, termB_1st_digit, -offset)
- /* If signs were changed apply result_sign. */
- daca (result_sign = -1) {
- daca (termB_1st_digit > 0) {
- termB[0] <- '-'
- }
- altfel {
- lenB <- arrnfill(termB, lenB, 0, 1, '-')
- }
- }
- altfel daca (termB_1st_digit > 0) { // (Pozitive result) If termB has sign remove it.
- lenB <- arrnshift(termB, lenB, 0, -1)
- }
- return lenB
- }
- Intreg arrborrow(Intreg arr[], Intreg poz, Intreg base)
- {
- Intreg i, found
- i <- poz - 1 // The next position to look for borrow.
- found <- 0 // Whether there is "lender" to borrow from.
- /* Find "lender" right to left and borrow, if possible. */
- while ( i >= 0 AND !found;) {
- daca (arr[i] AND arr[i] < base) {
- arr[i]--
- found <- 1
- }
- i--
- }
- /* No "lender". */
- daca (!found) {
- return -1
- }
- /* Else lender was found, and borrowed from "it". */
- /* Distribute the borrow, left to right. */
- for (i += 2; i < poz; i++) {
- arr[i] += base - 1
- }
- /* The borrower gets full unit. */
- arr[i] += base
- return base
- }
- Intreg arradd(Intreg termA[], Intreg termB[], Intreg lenA, Intreg lenB, Intreg base)
- {
- /* Find sign, if any. (1 for +, -1 for -, 0 for not found.) */
- Intreg signA <- find_sign(termA)
- Intreg signB <- find_sign(termB)
- // Skip sign OR set sign to 1 if no sign was found.
- Intreg termA_1st_digit, termB_1st_digit
- termA_1st_digit <- termB_1st_digit <- 0
- daca (signA) {
- termA_1st_digit++
- }
- altfel {
- signA <- 1
- }
- daca (signB) {
- termB_1st_digit++
- }
- altfel {
- signB <- 1
- }
- /* If signs are different, return call arrsub. */
- daca (signA != signB) {
- daca (signA = -1) {
- /* -a + b = -a - (-b) */
- lenB <- arrnfill(termB, lenB, 0, 1, '-')
- returneaza arrsub(termA, termB, lenA, lenB, base)
- }
- altfel {
- /* a + (- b) = a - b */
- lenB = arrnshift(termB, lenB, 0, -1)
- returneaza arrsub(termA, termB, lenA, lenB, base)
- }
- }
- /* If termB (which will store the result) is smaller than termA. */
- daca (
- (lenB - termB_1st_digit) < (lenA - termA_1st_digit)
- )
- {
- /* Shift termB, starting at the first digit. */
- lenB <- arrnshift(termB, lenB, termB_1st_digit, lenA - lenB)
- }
- /* Operate */
- Intreg iA, jB
- /* Used for iterating. */
- iA <- lenA - 1
- jB <- lenB - 1
- Intreg sum, transport
- sum <- transport <- 0
- /* Right to left add. */
- while (
- iA >= termA_1st_digit AND
- jB >= termB_1st_digit
- )
- {
- sum <- termA[iA] + termB[jB] + transport
- termB[jB] <- sum % base
- transport <- (sum >= base) ? 1 : 0
- iA-- jB--;
- }
- /* While transport & there's more of termB (term[jB]-isDigit) add transport. */
- while (jB >= termB_1st_digit AND transport) {
- sum <- termB[jB] + transport
- termB[jB] <- sum % base
- transport <- (sum >= base) ? 1 : 0
- jB--
- }
- /* If there's transport: shift by 1, starting at the index of 1st_digit
- * and fill new position with 1 (transport)
- */
- daca (transport) {
- arrnfill(termB, lenB, termB_1st_digit, 1, transport)
- lenB++
- }
- returneaza lenB
- }
- Intreg arradd(Intreg termA[], Intreg termB[], Intreg lenA, Intreg lenB, Intreg base)
- {
- /* Find sign, if any. (1 for +, -1 for -, 0 for not found.) */
- Intreg signA <- find_sign(termA)
- Intreg signB <- find_sign(termB)
- // Skip sign OR set sign to 1 if no sign was found.
- Intreg termA_1st_digit, termB_1st_digit
- termA_1st_digit <- termB_1st_digit <- 0
- daca (signA) {
- termA_1st_digit++
- }
- altfel {
- signA <- 1
- }
- daca (signB) {
- termB_1st_digit++
- }
- altfel {
- signB <- 1
- }
- /* If signs are different, return call arrsub. */
- daca (signA != signB) {
- daca (signA = -1) {
- /* -a + b = -a - (-b) */
- lenB <- arrnfill(termB, lenB, 0, 1, '-')
- returneaza arrsub(termA, termB, lenA, lenB, base)
- }
- altfel {
- /* a + (- b) = a - b */
- lenB = arrnshift(termB, lenB, 0, -1)
- returneaza arrsub(termA, termB, lenA, lenB, base)
- }
- }
- /* If termB (which will store the result) is smaller than termA. */
- daca (
- (lenB - termB_1st_digit) < (lenA - termA_1st_digit)
- )
- {
- /* Shift termB, starting at the first digit. */
- lenB <- arrnshift(termB, lenB, termB_1st_digit, lenA - lenB)
- }
- /* Operate */
- Intreg iA, jB
- /* Used for iterating. */
- iA <- lenA - 1
- jB <- lenB - 1
- Intreg sum, transport
- sum <- transport <- 0
- /* Right to left add. */
- while (
- iA >= termA_1st_digit AND
- jB >= termB_1st_digit
- )
- {
- sum <- termA[iA] + termB[jB] + transport
- termB[jB] <- sum % base
- transport <- (sum >= base) ? 1 : 0
- iA-- jB--;
- }
- /* While transport & there's more of termB (term[jB]-isDigit) add transport. */
- while (jB >= termB_1st_digit AND transport) {
- sum <- termB[jB] + transport
- termB[jB] <- sum % base
- transport <- (sum >= base) ? 1 : 0
- jB--
- }
- /* If there's transport: shift by 1, starting at the index of 1st_digit
- * and fill new position with 1 (transport)
- */
- daca (transport) {
- arrnfill(termB, lenB, termB_1st_digit, 1, transport)
- lenB++
- }
- returneaza lenB
- }
- Intreg arradd(Intreg termA[], Intreg termB[], Intreg lenA, Intreg lenB, Intreg base)
- {
- /* Find sign, if any. (1 for +, -1 for -, 0 for not found.) */
- Intreg signA <- find_sign(termA)
- Intreg signB <- find_sign(termB)
- // Skip sign OR set sign to 1 if no sign was found.
- Intreg termA_1st_digit, termB_1st_digit
- termA_1st_digit <- termB_1st_digit <- 0
- daca (signA) {
- termA_1st_digit++
- }
- altfel {
- signA <- 1
- }
- daca (signB) {
- termB_1st_digit++
- }
- altfel {
- signB <- 1
- }
- /* If signs are different, return call arrsub. */
- daca (signA != signB) {
- daca (signA = -1) {
- /* -a + b = -a - (-b) */
- lenB <- arrnfill(termB, lenB, 0, 1, '-')
- returneaza arrsub(termA, termB, lenA, lenB, base)
- }
- altfel {
- /* a + (- b) = a - b */
- lenB = arrnshift(termB, lenB, 0, -1)
- returneaza arrsub(termA, termB, lenA, lenB, base)
- }
- }
- /* If termB (which will store the result) is smaller than termA. */
- daca (
- (lenB - termB_1st_digit) < (lenA - termA_1st_digit)
- )
- {
- /* Shift termB, starting at the first digit. */
- lenB <- arrnshift(termB, lenB, termB_1st_digit, lenA - lenB)
- }
- /* Operate */
- Intreg iA, jB
- /* Used for iterating. */
- iA <- lenA - 1
- jB <- lenB - 1
- Intreg sum, transport
- sum <- transport <- 0
- /* Right to left add. */
- while (
- iA >= termA_1st_digit AND
- jB >= termB_1st_digit
- )
- {
- sum <- termA[iA] + termB[jB] + transport
- termB[jB] <- sum % base
- transport <- (sum >= base) ? 1 : 0
- iA-- jB--;
- }
- /* While transport & there's more of termB (term[jB]-isDigit) add transport. */
- while (jB >= termB_1st_digit AND transport) {
- sum <- termB[jB] + transport
- termB[jB] <- sum % base
- transport <- (sum >= base) ? 1 : 0
- jB--
- }
- /* If there's transport: shift by 1, starting at the index of 1st_digit
- * and fill new position with 1 (transport)
- */
- daca (transport) {
- arrnfill(termB, lenB, termB_1st_digit, 1, transport)
- lenB++
- }
- returneaza lenB
- }
- Intreg find_sign(Intreg term[])
- {
- daca (term[0] = '-') {
- returneaza -1
- }
- altfel daca (term[0] = '+') {
- return 1
- }
- // no sign
- returneaza 0
- }
Add Comment
Please, Sign In to add comment