- 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
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
Last edited: