5
\$\begingroup\$

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 
\$\endgroup\$

1 Answer 1

8
\$\begingroup\$
//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.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.