• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[vJASS] Optimize Addition Algorithm

Status
Not open for further replies.
Just want to see if anyone has any ideas for optimizing the following further. This algorithm is used for both addition/subtraction (see the sign parameter). It can handle negative and positive numbers.

Step 1: Add up all digits and handle carries.
Step 2: If there is still a carry, keep going until the carry is 0.
Step 3: Get the final digit (remove all zeroes in front).
Step 4: Get the sign of the number (first digit in number).
Step 5: Give all manipulated digits the same sign as the sign of the number.
Step 6: Continue to set the sign of digits until the sign of the digit matches the sign of the number.
Step 7: Remove all front zeroes again.



Here is the code

JASS:
//! textmacro Add
    private struct Add extends array
        private static method addInner takes Number number, integer i, integer sign returns nothing
            local Number current = number
            local integer base = number.base
            local integer digit
            local integer multiplier
            
            if (Number(number.lastDigit).digit < 0) then
                set multiplier = -1
            else
                set multiplier = 1
            endif
            
            /*
            *   Add the numbers
            */
            loop
                exitwhen i == 0
                
                /*
                *   Calculate current digit
                *
                *       current.digit + i.pop(base)
                */
                set digit = current.digit + (i - i/base*base)*sign
                set i = i/base
                
                /*
                *   Compact current digit to base
                *   Add the overflow to the next digit
                */
                set current.digit = digit - digit/base*base
                set current = current + 1
                set current.digit = current.digit + digit/base
            endloop
            
            /*
            *   Carry overflow
            */
            loop
                if (current.digit < 0) then
                    exitwhen -current.digit < base
                else
                    exitwhen current.digit < base
                endif
                
                set digit = current.digit
                
                set current.digit = digit - digit/base*base
                set current = current + 1
                set current.digit = current.digit + digit/base
            endloop
            
            /*
            *   Update final digit of number
            */
            if (integer(current) >= number.lastDigit) then
                loop
                    exitwhen current.digit != 0 or integer(current) == integer(number)
                    set current = current - 1
                endloop
                
                set number.lastDigit = current
            endif
            
            /*
            *   Normalize the signs of the digits in the number
            */
            if (i < 0) then
                set sign = -sign
            endif
            
            if (multiplier != sign) then
                if (Number(number.lastDigit).digit < 0) then
                    set multiplier = -1
                else
                    set multiplier = 1
                endif
            
                /*
                *   First update all manipulated digits
                */
                set digit = current
                set current = number
                loop
                    if (current.digit < 0) then
                        set sign = -1
                    elseif (current.digit > 0) then
                        set sign = 1
                    else
                        set sign = multiplier
                    endif
                    
                    if (sign != multiplier) then
                        set current.digit = current.digit + base*multiplier
                        set Number(current + 1).digit = Number(current + 1).digit - multiplier
                    endif
                
                    set current = current + 1
                    exitwhen integer(current) > digit
                endloop
                /*
                *   Next update signs of digits that may have been manipulated via carries
                *   Continue to update until the signs match
                */
                set digit = number.lastDigit
                loop
                    if (current.digit < 0) then
                        set sign = -1
                    elseif (current.digit > 0) then
                        set sign = 1
                    else
                        set sign = multiplier
                    endif
                    
                    exitwhen sign == multiplier
                    
                    set current.digit = current.digit + base*multiplier
                    set current = current + 1
                    set current.digit = current.digit - multiplier
                endloop
                
                /*
                *   Update the final digit
                */
                if (integer(current) >= number.lastDigit) then
                    loop
                        exitwhen current.digit != 0 or integer(current) == integer(number)
                        set current = current - 1
                    endloop
                    
                    set number.lastDigit = current
                endif
            endif
        endmethod
    
        static method add takes Number number, integer i, integer sign returns nothing
            if (i != 0) then
                call addInner(number, i, sign)
            endif
        endmethod
    endstruct
//! endtextmacro
 

Attachments

  • BigInt.w3m
    41.3 KB · Views: 39
Last edited:
Status
Not open for further replies.
Top