PaperAndPencil

NAME

Arithmetic::PaperAndPencil - simulating paper and pencil techniques for basic arithmetic operations

SYNOPSIS


use Arithmetic::PaperAndPencil;

my Arithmetic::PaperAndPencil $operation .= new;
my Arithmetic::PaperAndPencil::Number $x .= new(value => '355000000');
my Arithmetic::PaperAndPencil::Number $y .= new(value => '113');

$operation.division(dividend => $x, divisor => $y);
my Str $html = $operation.html(lang => 'fr', silent => False, level => 3);
'division.html'.IO.spurt($html);

$operation .= new; # emptying previous content
my Arithmetic::PaperAndPencil::Number $dead .= new(value => 'DEAD', radix => 16);
my Arithmetic::PaperAndPencil::Number $beef .= new(value => 'BEEF', radix => 16);

$operation.addition($dead, $beef);
$html = $operation.html(lang => 'fr', silent => False, level => 3);
'addition.html'.IO.spurt($html);

The first HTML file ends with

 355000000|113
 0160     |---
  0470    |3141592
   0180   |
    0670  |
     1050 |
      0330|
       104|

and the second one with

  DEAD
  BEEF
 -----
 19D9C

DESCRIPTION

Arithmetic::PaperAndPencil is a module which allows simulating the paper and pencil techniques for basic arithmetic operations on integers: addition, subtraction, multiplication and division, but also square root extraction and conversion from a radix to another.

An object from the Arithmetic::PaperAndPencil class is called "paper sheet", because it represents a paper sheet on which the simulated human scribbles his computations. In some cases, the human would use a wad of sheets instead of a single sheet. This is simulated in the module, but we still called an object "paper sheet".

Problems, known bugs and acceptable breaks from reality

Most humans can only compute in radix 10. Some persons have a theoretical knowledge of numeric bases other than 10, and a limited practical skill of using radix 2, radix 8 and radix 16. The module uses any radix from 2 to 36, without difference.

The module can use numbers of any length. Human beings will not be able to multiply two 100-digit numbers. Or if they try, they will spend much effort and the result may be wrong. The module can easily multiply two 100-digit numbers. The output may be lengthy and boring, but it will be correct.

Humans can detect situations where the computation procedure can be amended, such as a multiplication where the multiplicand and the multiplier contain many "0" digits. The module does not detect these cases and still uses the unaltered computation procedure.

Human beings write their calculations on A4 paper (21 cm Ɨ 29,7 cm) or letter paper (21,6 cm Ɨ 27,9 cm). The module writes its calculations on unlimited sheets of paper. If you want to compute the product of two 1000-digit numbers, the multiplication will have a 2000-char width and a 1000-line height and still be on a single sheet of paper.

If you ask for the operations with the "talking" formulas, most of these formulas are the traditional sentences which accompanies the writing of the computation. But in some cases, the module displays a non-standard sentence, to explain better what is happening.

UTILITY METHODS

new

Without parameters, creates an empty paper sheet. Or removes the content of an already existing paper sheet.

With a csv keyword parameter, reads a CSV file and creates a paper sheet containing the operations listed in this CSV file. The parameter is the CSV filename.

csv

Generates a string with a CSV format and listing all operations stored in the sheet object. Storing this string into a file allows you to use the < .new(csv => $filename) > method to recreate a prior sheet.

html

Generates a string using the HTML format.

For a properly formatted HTML file, the module user should provide the beginning of the file, from the < <html> > tag until the < <body> > tag, and then the end of the file, with the C<< </body></html> >> tags.

The parameters are the following:

  • lang

    The language for the titles and messages. The "fr" language is fully specified, and the "en" language is still incomplete. For the moment, there are no other languages.

  • silent

    Boolean parameter controlling the display of the "spoken" messages. If True, only the titles are displayed. It False, all messages are displayed.

  • level

    Integer parameter controlling the display of partial operations. If 0, only the final complete operation is shown. If 1, each sheet is displayed upon switching to another sheet (when using a wad of sheets). If 2 or more, partial operations are displayed. The higher the parameter, the more often the partial operations are displayed.

  • css

    Overrides the default HTML formatting. This is a hash table, with entries among underline, strike, write, read and talk. If an entry exists, the default format is replaced by < <span style='xxx'> >. Exception: if the talk entry exists, the "spoken" messages are formatted with < <p style='xxx'> >.

ARITHMETIC METHODS

All these methods return a Arithmetic::PaperAndPencil::Number instance, equal to the result of the operation. Unless specified otherwise, all input Arithmetic::PaperAndPencil::Number instances must have the same numeric radix.

addition

Simulates the addition of two or more numbers. The numbers are given as a list variable @list or a list of scalar variables $nb1, $nb2, $nb3. This is a positional parameter. Each number is an instance of the Arithmetic::PaperAndPencil::Number class.

subtraction

Simulates the subtraction of two numbers, instances of the Arithmetic::PaperAndPencil::Number class. The keywords are high and low. The high number must be greater than or equal to the low number. Negative results are not allowed.

A third keyword parameter is type. With this parameter, you can choose between a standard subtraction (parameter value std, default value) and a subtraction using the radix-complement of the low number (parameter value compl).

Acceptable break from reality. When using the compl variant, the module will write the extra digit and then strike it, while the human computer will stop before writing this extra digit, especially in the context of assembly programming, where for example the registers hold 32 bits, not 33.

multiplication

Simulates the multiplication of two numbers. The keyword parameters are:

  • multiplicand, multiplier

    The two numbers to be multiplied, instances of Arithmetic::PaperAndPencil::Number.

  • type

    Specifies the variant technique. This parameter is a Str value. The default variant is 'std'. Other values are 'jalousie-A', 'jalousie-B', or 'boat' (see below).

  • direction

    This parameter is used with the 'boat' type. Value 'ltr' (default value) specifies that the elementary products are processed left-to-right, value 'rtl' specifies that these products are processed right-to-left. This applies only to processing the multiplier's digits. Whatever the value, the digits of the multiplicand are processed left-to-right.

    This parameter has no use with 'std', 'jalousie-A' and jalousie-B' types.

  • mult-and-add

    This parameter is used with the 'boat' type. Value 'separate' (default value) means that in a first phase, the digits resulting from the elementary multiplications are written and that in a second phase these digits are added together to obtain the final result. Value 'combined' means that as soon as a elementary product is computed, its digits are added to the running sum which will become the final full product at the end.

    This parameter has no use with 'std', 'jalousie-A' and jalousie-B' types.

  • product

    This parameter is used with the "jalousie-*" types. Value "L-shaped" (default value) means that the product is written in two parts, an horizontal one at the bottom of the operation and an vertical one, on the left side of the operation for "jalousie-A" or on the right side for "jalousie-B". Value "straight" means than the product is written horizontaly on the bottom line, even if the bottom line is wider than the rectangle of the operation.

The various types are

  • std

    The standard multiplication.

    Acceptable break from reality: remember that the successive partial products shifts by one column. These shifts are materialised with dots. When the multiplier contains a digit 0, the line with all zeroes is not printed and the shift is more than one column, with the corresponding number of dots. Example:

    .      628
      .      203
      .      ---
      .     1884
      .   1256..
      .   ------
      .   127484
    

    The actual acceptable break from reality happens when the multiplier contains zeroes at the right. In this case, are there dots in the very first line? Or do we write zeroes? See below both cases.

    .      628          628
      .      230          230
      .      ---          ---
      .    1884.        18840
      .   1256..       1256..
      .   ------       ------
      .   144440       144440
    

    The module uses the second possibility, writing zeroes on the first line.

  • shortcut

    The standard multiplication, but if the multiplier contains repeated digits, the partial products are computed only once. When the same digit appears a second time in the multiplier, the partial product is copied from the first occurrence instead of being recomputed.

  • prepared

    This variant is inspired from the prepared variant for the division. Before starting the multiplication proper, all partial products are preemptively computed. Then, when the multiplication is computed, all partial products are simply copied from the preparation step.

    Acceptable break from reality: there is no evidence that this technique is taught or used. It is just an possible extension to multiplication of the prepared division technique.

  • jalousie-A

    The partial products are written in rectangular form. The multiplicand is written left-to-right on the top side of the rectangle, the multiplier is written top-to-bottom on the right side of the rectangle, the final product is written first, top-to-bottom on the left side of the rectangle and second, left-to-right on the bottom side of the rectangle. For example, the multiplication 15 Ɨ 823 = 12345 gives the following result (omitting the interior of the rectangle):

    .     823
      .    1   1
      .    2   5
      .     345
    

    If the product parameter is "straight", then the operation final aspect is:

    .     823
      .        1
      .        5
      .   12345
    

    Acceptable break from reality: the outlying digits should be centered with respect to the inner grid. The module writes them in a skewed fashion. In addition, the inner vertical and horizontal lines are not drawn. Below left, the theoretical output, below right the simplified output:

    .     8   2   3         8 2 3
      .   -------------      --------
      .   |0 /|0 /|0 /|      |0/0/0/|
      .  1| / | / | / |1    1|/8/2/3|1
      .   |/ 8|/ 2|/ 3|      |4/1/1/|
      .   -------------     2|/0/0/5|5
      .   |4 /|1 /|1 /|      --------
      .  2| / | / | / |5      3 4 5
      .   |/ 0|/ 0|/ 5|
      .   -------------
      .     3   4   5
    
  • jalousie-B

    The partial products are written in rectangular form. The multiplicand is written left-to-right on the top side of the rectangle, the multiplier is written bottom-to-top on the left side of the rectangle, the final product is written first, left-to-right on the bottom side of the rectangle and second, bottom-to-top on the right side of the rectangle. For example, the multiplication 15 Ɨ 823 = 12345 gives the following result (omitting the interior of the rectangle):

    .  823
      . 5   5
      . 1   4
      .  123
    

    If the product parameter is "straight", then the operation final aspect is:

    .  823
      . 5
      . 1
      .  12345
    

    Acceptable break from reality: same as for 'jalousie-A'.

  • boat

    The multiplicand is written between two horizontal lines. The multiplier is written below the bottom line and stricken and rewritten as the multiplication progresses. The partial products are written above the top line. When the partial products are added, they are stricken and the final product is written above the partial products.

    Acceptable break from reality: I am not sure the explanation from Number Words and Number Symbols is authoritative. So I have added two parameters, direction and mult-and-add, to allow the module user to choose which subvariant he prefers.

division

Simulates the division of two numbers. The keyword parameters are:

  • dividend, divisor

    The two numbers to be divided, instances of Arithmetic::PaperAndPencil::Number.

  • type

    Specifies the variant technique. This parameter is a Str value. The default variant is "std".

  • result

    This Str parameter can be either "quotient" (default value) or "remainder", or "both". It controls which value is (are) returned by the method to the main programme.

  • mult-and-sub

    This Str parameter can be either "combined" (default value) or "separate". It controls the computation of the successive partial remainders with a multiplication (quotient digit times full divisor) and a subtraction (from the partial dividend). If "combined", the multiplication and the subtraction are done at the same time, digit per digit. If "separate", the multiplication is done first in full, then the subtraction is done.

The various types are

  • std

    The standard division.

  • cheating

    This is the standard division with a twist. The standard division is usually a trial-and-error process in which several candidate digits are tried for each quotient digit. With this technique, the trial-and-error process is cut short and only the successful digit is tried.

    Acceptable break from reality: This is not a real method, this is a convenience method which gives shorter HTML files than what the "std" type generates.

  • prepared

    Before starting the division, the module computes the partial products of the divisor with any single-digit number. These when computing the intermediate remainders, instead of doing a multiplication - subtraction combination, the already known partial product is simply copied from the preparation list then subtracted from the previous intermediate remainder. The mult-and-sub parameter defaults to "separate" for this division type.

  • boat

    The dividend is written above an horizontal line. The divisor is written below this line. As the first partial remainder is computed, the used digits of the dividend and divisor are stricken and the digits of the partial remainder are written above the digits of the dividend. When computing the next digits, the divisor is rewritten and the computation of the next partial remainder again strikes the digits of the first partial remainder and of the second occurrence of the divider.

    Acceptable break from reality: I have not found anywhere an explanation for this technique. The way it is implemented is just some guesswork after some reverse engineering attempt. A special point is that it seems to require something similar to the cheating technique above, because I do not see how we can "unstrike" the digits that were stricken with the previous digit candidate.

square-root

Simulates the extraction of the square root of a number. There is a single positional parameter, an instance of the Arithmetic::PaperAndPencil::Number class.

There is an optional keyword parameter, mult-and-sub. Its purpose is the same as for division. If set to 'combioned' (default value), the computing of the product (candidate digit times divisor) is combined with the subtraction from the partial dividend. If set to 'separate', the multiplication and the subtraction are executed in separate and successive phases.

conversion

Simulates the conversion of a number from its current radix to a new radix.

The parameters are:

  • number

    The number to convert, instance of Arithmetic::PaperAndPencil::Number.

  • radix

    The destination radix for the conversion. This is a native Int number, not an instance of Arithmetic::PaperAndPencil::Number.

  • nb-op

    The number of operations on a single page. After this number is reached, a new page is generated. This allows keeping the complete operation sufficiently short. This parameter is a native Int number. If zero (default value), no new pages are generated.

  • type

    A string parameter specifying which algorithm is used to convert a number. Values 'mult' and 'Horner' are synonymous and use the cascading multiplication algorithm (or Horner scheme). Value 'div' uses the cascading division algorithm.

  • div-type

    A string parameter specifying which kind of division is used: 'std' (default value) uses a standard division with a full trial-and-error processing for candidate quotient digits, 'cheating' uses a standard division in which the trial-and-error of candidate quotient digits is artificially reduced to a single iteration, 'prepared' first computes the list of multiples for the target radix and uses it to openly and accountably reduce the trial-and-error processing to a single iteration.

    This parameter is ignored if the conversion parameter type is not 'div'.

    See the type parameter for the division method. Yet, the 'boat' value available for the type parameter of the division method is not allowed for the div-type parameter of the conversion method.

  • mult-and-sub

    This parameter is similar to the mult-and-sub parameter for the division method, except that it is useful only if the value of the div-type parameter is 'cheating'.

    The parameter controls the computation of the successive partial remainders with a multiplication (quotient digit times full divisor) and a subtraction (from the partial dividend). Possible values are 'combined' or 'separate'. If 'combined', the multiplication and the subtraction are done at the same time, digit per digit. If 'separate', the multiplication is done first in full, then the subtraction is done.

    If the div-type parameter is 'prepared', this parameter is ignored and the multiplication and the subtraction are done separately.

    If the div-type parameter is 'std', the mult-and-sub parameter is ignored and the multiplication and the subtraction are combined. The reason for this behaviour is to by-pass a bug which would appear in cramped situations where several divisions are crammed side by side.

gcd

Simulates the computation of the GCD (greatest common divisor) of two numbers.

The parameters are:

  • first

    The first number used, instance of Arithmetic::PaperAndPencil::Number.

  • second

    The second number used, instance of Arithmetic::PaperAndPencil::Number.

  • div-type

    A string parameter specifying which kind of division is used: "std" (default value) uses a standard division with a full trial-and-error processing for candidate quotient digits, "cheating" uses a standard division in which the trial-and-error of candidate quotient digits is artificially reduced to a single iteration.

    See the type parameter for the division method. Yet, the "boat" and "prepared" values available for the type parameter of the division method are not allowed for the div-type parameter of the gcd method.

BUGS, ISSUES AND ACCEPTABLE BREAKS FROM REALITY

For the various arithmetical methods, not all parameter combinations are used in real life. This includes especially the "cheating" variants.

The values assigned to the level attribute are not always consistent and they may lead to awkward listings, in which a boring part is printed in whole detail and an interesting part is printed without enough detail.

SECURITY MATTERS

As said above, the numbers are not limited in length. The flip side is that the user can ask for the multiplication of two 1000-digit numbers, which means several millions of basic actions (single-digit multiplications, basic additions, etc). This can lead to a DOS-like situation: filled-up memory, clogged CPU for example.

Another issue is the initialisation of a Arithmetic::PaperAndPencil object with a CSV file. The content of the CSV file is not checked. This can result is line and column coordinates ranging in the thousands or beyond. In this case, the html method will build a huge string result.

SEE ALSO

The background of this module is extensively described in the Github repository. See https://github.com/jforget/raku-Arithmetic-PaperAndPencil/blob/master/doc/Description-en.md (or https://github.com/jforget/raku-Arithmetic-PaperAndPencil/blob/master/doc/Description-fr.md if you speak French).

DEDICATION

This module is dedicated to my primary school teachers, who taught me the basics of arithmetics, and even some advanced features, and to my secondary school math teachers, who taught me other advanced math concepts and features.

AUTHOR

Jean Forget <[email protected]>

COPYRIGHT AND LICENSE

Copyright 2023, 2024 Jean Forget

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.

Arithmetic::PaperAndPencil v0.0.1

Simulating paper-and-pencil techniques for basic arithmetic operations

Authors

  • Jean Forget

License

Artistic-2.0

Dependencies

Test Dependencies

Provides

  • Arithmetic::PaperAndPencil
  • Arithmetic::PaperAndPencil::Action
  • Arithmetic::PaperAndPencil::Char
  • Arithmetic::PaperAndPencil::Label
  • Arithmetic::PaperAndPencil::Number

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.