• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[vJASS] Optimize Addition Algorithm

Status
Not open for further replies.
Level 31
Joined
Jul 10, 2007
Messages
6,306
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: 37
Last edited:
Status
Not open for further replies.
Top