You can see it live here: https://flatassembler.github.io/multiplying-strings-aec.html
Function get_length_of_the_first_number() Which Returns Integer32 Is External;
Function get_digit_of_the_first_number_at(Integer32 index) Which Returns Character Is External;
Function get_length_of_the_second_number() Which Returns Integer32 Is External;
Function get_digit_of_the_second_number_at(Integer32 index) Which Returns Character Is External;
Function putc(Character char) Which Returns Nothing Is External;
Function logString(PointerToCharacter string) Which Returns Nothing Is External;
Character matrix[100*100];
Function f(Integer16 i, Integer16 j) Which Returns Integer32 Does
Return i * 100 + j;
EndFunction
Character result[100];
Function get_length_of_the_result() Which Returns Integer16 Does
Integer16 i := 0;
While i < 100 Loop
If result[i]=0 Then
Return i;
EndIf
i += 1;
EndWhile
Return i;
EndFunction
Function prepend_a_character_to_the_result(Character char) Which Returns Nothing Does
Integer16 i := get_length_of_the_result() + 1;
While i > 0 Loop
result[i]:=result[i - 1];
i -= 1;
EndWhile
result[0] := char;
EndFunction
Function multiply() Which Returns Nothing Does
// Initializing the matrix...
Integer32 i := 0, j := 0;
While i < get_length_of_the_second_number() Loop
j := 0;
While j < get_length_of_the_first_number() + get_length_of_the_second_number() + 1 Loop
matrix[f(i,j)] := ' ';
j += 1;
EndWhile
i += 1;
EndWhile
logString("The matrix is successfully filled with spaces.");
//Filling up the matrix...
Integer32 pointer_to_the_digit_in_the_second_number := 0;
While pointer_to_the_digit_in_the_second_number < get_length_of_the_second_number() Loop
Integer16 carry := 0,
pointer_to_the_matrix_column := get_length_of_the_first_number() +
pointer_to_the_digit_in_the_second_number + 1;
Integer16 pointer_to_the_digit_in_the_first_number := get_length_of_the_first_number() - 1;
While pointer_to_the_digit_in_the_first_number >= 0 Loop
Integer16 product :=
(get_digit_of_the_first_number_at(pointer_to_the_digit_in_the_first_number) - '0') *
(get_digit_of_the_second_number_at(pointer_to_the_digit_in_the_second_number) - '0') +
carry;
matrix[f(pointer_to_the_digit_in_the_second_number, pointer_to_the_matrix_column)]
:= mod(product, 10) + '0';
If product >= 10 Then
carry := product / 10;
Else
carry := 0;
EndIf
pointer_to_the_matrix_column -= 1;
pointer_to_the_digit_in_the_first_number -= 1;
EndWhile
If carry Then
matrix[f(pointer_to_the_digit_in_the_second_number,pointer_to_the_matrix_column)] :=
mod(carry, 10) + '0';
EndIf
If carry >= 10 Then
pointer_to_the_matrix_column -= 1;
matrix[f(pointer_to_the_digit_in_the_second_number, pointer_to_the_matrix_column)] :=
carry / 10 + '0';
EndIf
pointer_to_the_digit_in_the_second_number += 1;
EndWhile
logString("The matrix is now filled with the products of the first number and the digits of the second.");
//Summing up the matrix...
result[0]:=0;
Integer16 carry := 0;
i := get_length_of_the_first_number() + get_length_of_the_second_number();
While i >= 0 Loop
Integer32 sum := carry;
j := 0;
While j < get_length_of_the_second_number() Loop
If not(matrix[f(j, i)] = ' ') Then
sum += matrix[f(j, i)] - '0';
EndIf
j += 1;
EndWhile
prepend_a_character_to_the_result(mod(sum, 10) + '0');
carry := sum / 10;
i -= 1;
EndWhile
If carry Then
prepend_a_character_to_the_result(carry + '0');
EndIf
logString("The matrix is now summed up and the product of the two numbers is calculated.");
//Replace the trailing zeros with spaces. Now that's a lot easier to do in AEC than in JavaScript...
i := 0;
While result[i] = '0' Loop
result[i] := ' ';
i += 1;
EndWhile
logString("The trailing zeros in the result are now replaced by spaces.");
//Print the result...
putc(' ');
putc(' ');
i := 0;
While i < get_length_of_the_first_number() Loop
putc(get_digit_of_the_first_number_at(i));
i += 1;
EndWhile
putc('*');
i := 0;
While i < get_length_of_the_second_number() Loop
putc(get_digit_of_the_second_number_at(i));
i += 1;
EndWhile
putc('\n');
i := 0;
While i < get_length_of_the_first_number() + get_length_of_the_second_number() + 1 + 2 Loop
putc('-');
i += 1;
EndWhile
putc('\n');
i := 0;
While i < get_length_of_the_second_number() Loop
j := 0;
While j < get_length_of_the_first_number() + get_length_of_the_second_number() + 1 Loop
putc(matrix[f(i,j)]);
j += 1;
EndWhile
putc('\n');
i += 1;
EndWhile
i := 0;
While i < get_length_of_the_first_number() + get_length_of_the_second_number() + 1 Loop
putc('-');
i += 1;
EndWhile
putc('\n');
i := 0;
While result[i] Loop
putc(result[i]);
i += 1;
EndWhile
putc('\n');
logString("The result should be visible on the screen now!");
EndFunction
1 Answer 1
//Replace the trailing zeros with spaces. Now that's a lot easier to do in AEC than in JavaScript... i := 0; While result[i] = '0' Loop result[i] := ' '; i += 1; EndWhile
If the result is zero, this doesn't leave a single zero, the entire number is gone. You can compensate for that later too.
If product >= 10 Then carry := product / 10; Else carry := 0; EndIf
carry := product / 10;
is enough, you don't need the other case, the carry will be naturally zero anyway.
Character matrix[100*100];
If you add a partial product to the result while forming it, you don't need to store partial products temporarily before adding them. Not having to deal with that matrix could simplify the code in several places.
Regarding prepend_a_character_to_the_result
, prepending characters in this way is awkward, I suggest doing something to avoid it. For example:
- Building the result at the end of the array, printing the result "from the middle" (wherever the leading digit ends up).
- Building the result from the least significant digit up, printing it in reverse.
If you want to be fancy, you can merge a small chunk of adjacent digits into one, eg take 4 digits to form a number between 0 and 9999 (inclusive range) and do the multiplication in base 10000 (I chose 10000 because the product still fits in a 32-bit integer, and the conversion back to decimal is simple unlike a power-of-two base). Reducing the number of "digits" by a factor of about 4 that way reduces the number of multiplications by a factor of about 16x. A lot more algorithmic trickery is possible but that may not quite fit this question, I'd be happy to add it if you want.
Explore related questions
See similar questions with these tags.