I think one reason you have a bug is that there is just too much going on in the one function. As Nis$hant inferred you should compartmentalise things.
Also I don't think you need all the array shuffling and IMO read_keypad() should return a human-readable value, ie 0-9 and + etc.
For example here's is a simpler way (I think)
long num1;
long num2;
long result;
long *curr_num = num1;
byte key;
loop () {
key = read_keypad(); // this should return an int == to the numeric key entered or obvious values for '=' etc
switch (key) {
case '+':
if (curr_num == num1) { // if first number just start accululating into second number
curr_num = num2;
} else {
addNumbers(); // if the second number add them
}
break;
case '=':
addNumbers();
break;
default:
accumulateNumber();
display_number(curr_num);
}
}
void addNumbers () {
result = num1 + num2;
display_number(result);
curr_num = num1;
num1 = 0;
num2 = 0;
}
void accumulateNumber () {
*curr_num *= 10;
*curr_num += key;
}
void display_number(long * num){
for (int x = 0; x < 8, x++) {
shiftNum (num % 10); // send digit out
num /= 10;
}
}
This is little more than psuedo code and there's no error checking etc but I think it's easy to follow and if there's a bug it should be easy to isolate.
Rob