### ----------------------------------------------------
### -- Arithmetic::PaperAndPencil
### -- Licenses: Artistic-2.0
### -- Authors: Jean Forget
### -- File: doc/Description-fr.md
### ----------------------------------------------------
### -- Chunk 1 of 5
-*- encoding: utf-8; indent-tabs-mode: nil -*-

Introduction
============

Le module  a pour but de  simuler les opérations arithmétiques  par un
humain qui ne dispose pas de calculatrice, mais simplement de quelques
feuilles de papier et d'un crayon.

Historique
==========

Pendant les  années 1960 (en  débordant un  peu sur les  années 1970),
j'ai  appris les  quatre opérations  de base,  addition, soustraction,
multiplication et division.

![Exemple de calcul provenant d'un de mes cahiers](calcul-1970-12-02.png)

En 1976,  j'ai appris également  à extraire des racines  carrées, avec
une méthode très proche de la division en « potence » apprise quelques
années plus tôt.

```
200000000|14142
100      |-----
 0400    |24
  11900  | 4
   060400|---
    03936|281
         |  1
         |----
         |2824
         |   4
         |-----
         |28282
         |    2
         |
```

En 1979,  mon père a  reçu des photocopies d'un  cahier d'arithmétique
datant de 1822. Ce cahier  contient des divisions assez différentes de
ce que  mon père  et moi  connaissons. J'ai  fait un  peu d'ingéniérie
inverse sur ce cahier et je  pense avoir retrouvé la méthode utilisée.
Néanmoins, c'est toujours hypothétique.

![Exemple de calcul provenant du cahier de 1822](calcul-1822.jpeg)

Voici les  deux premières divisions  de la page  présentée ci-dessus :
24696000 divisé par 25882 donne 954, reste 4572 et 34048000 divisé par
25882 donne 1315, reste 13170.  Ces divisions correspondent aux règles
de trois (7000 ×  3528) / 25882 et (7000 × 4864)  / 25882. Vous pouvez
d'ailleurs  voir  les  multiplications   correspondantes  à  côté  des
divisions. La  transcription ci-dessous ne  montre pas que  les restes
4572 et 13170 sont soulignés par un trait oblique.

<pre>
   0<u>4</u>                   <u>13</u>
  <strike>108</strike><u>5</u>                 <strike>142</strike><u>1</u>
 <strike>14021</strike><u>7</u>               <strike>04015</strike><u>7</u>
<strike>2469620</strike><u>2</u>             <strike>0816648</strike><u>0</u>
<u><strike>24696000</strike></u>{0954        <u><strike>34048000</strike></u>{1315
--------             --------
<strike>25882222</strike>             <strike>25882222</strike>
 <strike>258888</strike>               <strike>258888</strike>
  <strike>2588</strike>                 <strike>2588</strike>
   <strike>25</strike>                   <strike>25</strike>
</pre>

Si vous trouvez  illisibles les chiffres barrés, voici  de nouveau les
deux divisions, sans barrer les chiffres.

```
   04                 13
  1085               1421
 140217             040157
24696202           08166480
24696000{0954      34048000{1315
--------           --------
25882222           25882222
 258888             258888
  2588               2588
   25                 25
```

En 1982, pour un projet d'histoire des sciences, j'ai emprunté _Number
Words  and Number  Symbols, A  Cultural History  of Numbers_,  de Karl
Menninger, je l'ai lu et je l'ai rendu à la bibliothèque.

En 1996,  j'ai acheté et lu  _Histoire d'Algorithmes, du caillou  à la
puce_.

En 2000  ou 2001, j'ai  écrit un programme Perl  permettant d'extraire
des racines  carrées avec  la méthode  de la  potence. Ce  programme a
disparu de la circulation et je ne m'en porte pas plus mal.

En 2005, aux
[Journées Perl à Marseille](https://journeesperl.fr/fpw2005/)
j'ai présenté une communication éclair sur
[comment extraire une racine carrée](https://journeesperl.fr/fpw2005/talk/201).
La démonstration était uniquement avec  un feutre (émulant un crayon),
un transparent et un rétro-projecteur (émulant une feuille de papier).
Il n'y  avait pas de  programme informatique. C'était prévu  pour « un
jour ou l'autre ». Voici le transparent de cet exposé, montrant que la
racine carrée de 65549,00 est 256,0, avec un reste de 13,00.

![calcul de racine carrée](racine-carree.jpeg)

```
6554900|256,0
255    |-----
 3049  |45
  01300| 5
       |--
       |506
       |  6
       |---
       |5120
       |   0
```

En  2009,  j'ai acheté  un  exemplaire  de  _Number Words  and  Number
Symbols, A  Cultural History  of Numbers_  et j'ai  pu le  consulter à
loisir, sans être contraint de le rapporter à la bibliothèque.

En 2023, je  commence à écrire ce  programme en Raku et  sous la forme
d'un module.

But
===

Le calcul se fait à deux niveaux. Prenons le cas de la multiplication.
Il  y  a  d'abord  le  calcul mental,  où  l'écolier  est  capable  de
multiplier deux nombres à  un chiffre pour obtenir un nombre  à 1 ou 2
chiffres. Il y  a ensuite le calcul sur papier,  où l'écolier enchaîne
les opérations  élémentaires pour  obtenir la  multiplication complète
d'un nombre à _n_ chiffres par un nombre à _n'_ chiffres.

Le module contient principalement deux classes. La première est la classe des
nombres, où les opérations sont très limitées, correspondant au calcul
mental  sans  papier.  Par  exemple,  la  multiplication  est  définie
uniquement pour deux facteurs à un seul chiffre.

La  deuxième classe  représente  une feuille  de  papier (ou  quelques
feuilles).  Le  principal  attribut  de cette  classe  est  une  liste
d'actions, représentant  l'écolier lisant des chiffres  déjà inscrits,
effectuant un calcul élémentaire et  écrivant le résultat de ce calcul
sur la  feuille de papier,  tout en prononçant les  phrases convenues,
telles que :

```
  6 fois 8, 48
  je pose 8 et je retiens 4
```

La  classe comporte  plusieurs méthodes  correspondant aux  opérations
arithmétiques,  addition,  soustraction, multiplication,  division  et
racine  carrée.   Ces  méthodes  alimentent  l'attribut   « liste  des
actions ». Une autre méthode affiche ces actions au format HTML. Selon
les paramètres, l'affichage ne comporte que les chiffres mis en forme,
ou  bien l'affichage  énumère en  plus les  phrases prononcées  par la
personne censée effectuer le calcul.

On peut envisager d'autres méthodes d'affichage pour d'autres formats,
comme  le  texte  pur  ou  le  format  L<sup>A</sup>T<sub>E</sub>X  +
Metapost. Mais ce n'est pas une priorité.

Ce que le module ne fera pas
----------------------------

Il y a  des choses que je savais  faire à 10 ans mais que  je n'ai pas
prévu  de reprendre  dans le  module. Notamment,  je savais  faire des
opérations avec  des nombres à  virgule. Le  module ne traite  que des
nombres entiers. Tenir  compte de la virgule dans  les nombres traités
nécessiterait  l'ajout  de très  nombreuses  lignes  de code  pour  un
intérêt assez limité.  Donc en fait ma démo des  Journées Perl de 2005
ne pourra pas être reprise telle  quelle. Il faudra calculer la racine
carrée de 6554900 avec le module,  puis, après avoir quitté ce module,
insérer la virgule à l'endroit nécessaire. Ou alors, pour calculer une
valeur  approchée de  π à  6 décimales  avec la  fraction 355/113,  il
faudra à la place calculer la division 355_000_000 / 113 et insérer la
virgule juste après le premier chiffre.

Un  autre point.  Dans les  divisions, la  détermination des  chiffres
successifs du  quotient est  un processus  d'essais et  d'erreurs. Par
exemple, pour diviser  65400 par 1852, on commence  par se restreindre
au premier  chiffre du  dividende et au  premier chiffre  du diviseur,
soit  6   et  1,  ce qui donne  pour le quotient  le chiffre   6. En
voulant  calculer le  reste intermédiaire,  on voit  que  6   est trop
fort, donc on recommence avec  5.  5  est lui-même trop fort, donc on
recommence avec   4  puis  3   qui convient finalement.  Cela, c'était
l'apprentissage  basique.  Ultérieurement,  j'ai   appris  que  si  le
deuxième chiffre du  diviseur était  9  ou même  8,  on pouvait assez
souvent évaluer le  chiffre du diviseur en prenant  le premier chiffre
du diviseur, _plus  1_, avec le premier chiffre du du dividende, pour
déterminer le chiffre du quotient. Dans le cas de 65400 et de 1852, le
premier chiffre du quotient aurait été  évalué avec la division de 6
par  2, donc directement  3. Mon module ne fait pas cela. Toutefois,
il est prévu une option « triche » où le module élimine les tentatives
ratées de  6  puis de  5  et de  4. Cela donne dans le module

```
  En 6, combien de fois 1, il y va 6 fois.
  Mais je triche et j'essaie directement 3.
```

En fait,  cela revient  presque au  même, si ce  n'est que  mon module
passe plus de temps à faire des calculs qu'il abandonnera ensuite. Une
autre différence est que pour la division 74500 par 1852, l'évaluation
initiale 7/2 donne 3, alors que  le premier chiffre du quotient est 4.
Le module essaie 7, 6, 5 puis 4 sans essayer 3 qui est trop faible. Il
teste  donc uniquement  si  un chiffre  est trop  fort,  jamais si  un
chiffre est trop faible.

Est-il  indispensable d'ajouter  un  signe plus  (ou  plusieurs) à  la
gauche d'une addition,  un signe moins à la  gauche d'une soustraction
et  un signe  multiplier à  la gauche  d'une multiplication ?  Au tout
début de mes  leçons, c'est ce que j'ai appris,  mais très rapidement,
cela a  été abandonné.  De temps  à autre,  il m'arrivait  d'écrire un
signe  multiplier,   mais  en  règle  générale,   mes  multiplications
n'avaient pas de  signe. Le module n'écrira pas ces  signes. Une seule
exception,  la conversion  d'une base  à une  autre, qui  enchaîne les
multiplications avec les additions.  Pour une meilleure lisibilité, le
module ajoutera  les signes multiplier  et plus  là où ils  doivent se
trouver.

Le module utilise uniquement des  chiffres indo-arabo-latins (0, 1, 2,
3, etc).  Il n'est  pas prévu d'utiliser  des chiffres  indo-arabes (٠
pour 0, ١  pour 1, ٢ pour  2, ٣ pour 3,  ٤ pour 4, etc)  ou chinois ou
autres  systèmes  positionnels.  Et   encore  moins  les  systèmes  de
numération additifs  comme les hiéroglyphes égyptiens  et les chiffres
romains.

Un humain  suffisamment expérimenté (moi-même à  10 ans, mais pas  à 8
ans) est capable d'identifier des cas  de figure où l'on peut recourir
à des  simplifications, par  exemple lorsque  le multiplicateur  ou le
multiplicande  possède de  nombreux  chiffres à  zéro.  Mon module  ne
détectera pas  ces cas de  figure et suivra aveuglément  la procédure,
même si cela tourne au ridicule.

Mon module peut être considéré  comme un équivalent de `bigint`. C'est
vrai  tant que  l'on ne  s'intéresse pas  aux performances.  Un module
`bigint` a pour objectif des calculs performants en précision étendue,
ce n'est pas le cas de mon  module, qui a pour objectif des calculs en
précision étendue et décomposables en calculs simples.

Non seulement les performances ne sont pas au rendez-vous, mais il y a
l'ergonomie. Supposons  que l'on  veuille calculer  `√(b² -  4ac)`. Il
faudrait écrire un programme du genre :

```
my Arithmetic::PaperAndPencil::Number $a;
my Arithmetic::PaperAndPencil::Number $b;
my Arithmetic::PaperAndPencil::Number $c;
# initialisation de a, b et c, à compléter
...
# fin de l'initialisation, début du calcul
my Arithmetic::PaperAndPencil::Number $quatre .= new(value => '4');
my Arithmetic::PaperAndPencil::Number $resultat;

my Arithmetic::PaperAndPencil $feuille .= new;
$resultat = $feuille.squareroot($feuille.subtraction($feuille.multiplication($b, $b), $feuille.multiplication($quatre, $feuille.multiplication($a, $c))))
```

Et encore, dans l'exemple  ci-dessus, les paramètres sont prétendument
des  paramètres positionnels,  alors  que dans  la  réalité, ils  sont
spécifiés par des mots-clés.

Un  dernier point  où,  en fait,  je suis  d'accord  avec mon  module.
Lorsque l'on m'a enseigné les  opérations arithmétiques, j'ai appris à
ne pas  écrire les retenues, mais  à les conserver en  mémoire à court
terme. Mon module fera pareil, il n'écrira pas les retenues.

Ce que le module fera
---------------------

Lorsque j'avais 10  ans, je ne savais pas encore  extraire des racines
carrées, je ne connaissais pas la « variante 1822 » (ou variante « bateau ») de la division, ni
certaines autres variantes de la  multiplication et de la division. Le
module contiendra ces opérations et ces variantes.

La plupart  des êtres humains  savent calculer en base  10 uniquement.
Certains  ont une  connaissance limitée  des  calculs en  octal et  en
hexadécimal,  Mon  module  sera  capable de  faire  des  calculs  dans
n'importe quelle  base de 2  à 36. Ainsi,  la classe de  calcul mental
sait qu'en base  36, `Z × Z = Y1`  (équivalent en base 10 : 35  × 35 =
1225 = 36 × 34 + 1).

Lorsque j'ai appris  les bases de numération, j'ai  appris à convertir
les  nombres de  base 10  en  base _b_  en effectuant  une cascade  de
divisions  et à  convertir  les nombres  de  base _b_  en  base 10  en
effectuant  un calcul  de polynôme  avec le  schéma de  Horner (je  ne
savais pas que cela s'appelait le  schéma de Horner, je ne savais même
pas ce  qu'était un  polynôme, mais  peu importe,  je savais  faire le
calcul).  Mais je  n'ai pas appris à convertir  directement d'une base
_b_ à une  base _b'_. Ultérieurement, j'ai découvert  que certains cas
particuliers, comme  la conversion  de base 2  en base 4,  8 ou  16 ou
inversement,  peuvent donner  lieu à  un  calcul très  simple et  très
rapide. Mais je n'étais toujours pas  en mesure de convertir un nombre
directement de  la base  _b_ à la  base _b'_ dans  le cas  général. Le
module permettra de convertir un nombre  de base _b_ en base _b'_ pour
n'importe quelles bases entre 2 et 36.

Les nombres implémentés par le module  ne sont pas limités. Ou plutôt,
la limitation  est imposée par  l'interpréteur Raku et par  la machine
sur laquelle il est installé. Ainsi, il sera possible de reproduire la
multiplication de
[Frank Nelson Cole](https://fr.wikipedia.org/wiki/Frank_Nelson_Cole),
lorsqu'il a montré les diviseurs du
[67<sup>e</sup> nombre de Mersenne](https://fr.wikipedia.org/wiki/147_573_952_589_676_412_927)
en 1903.  Lorsque j'avais 10  ans, j'avais qualitativement  toutes les
connaissances nécessaires  pour effectuer  la même  multiplication que
Cole, mais  quantitativement cela  m'aurait demandé  trop de  temps et
trop d'efforts.

Lorsque j'ai appris à effectuer  des multiplications et des divisions,
j'ai appris les phrases qui vont avec (« En 6, combien de fois 1, il y
va 6 fois. »). Ces phrases sont, bien entendu, en français. Toutefois,
le module prévoit un mécanisme  de multi-linguisme. Donc, si je reçois
l'aide de  personnes anglophones,  germanophones ou autres,  le module
pourra écrire ces phrases en anglais, en allemand etc.

Une source de confusion éventuelle
----------------------------------

Les nombres utilisés par le module sont de deux natures distinctes. Il
y   a  les   nombres  qui   servent  au   calcul  demandé   (addition,
multiplication, racine carrée) et qui  sont des instances de la classe
`Arithmetic::PaperAndPencil::Number`. On trouve également dans cette
nature les morceaux de nombres : chiffres des unités, retenues, etc.
Et  il y a les  nombres annexes, qui servent à compter le nombre d'éléments dans un tableau ou
qui  servent à  exprimer les  bases de  numération et  les coordonnées
ligne-colonne pour  la mise  en forme  de l'opération.  Ces nombres-là
sont simplement des  `Int` natifs de Raku, ils ne  sont pas soumis aux
limites  du calcul  mental, comme  l'impossibilité de  multiplier deux
nombres si l'un des deux a plusieurs chiffres.

Opérations
==========

Addition
--------

Pas de variante, pas de cas particulier. Il n'y a rien à dire.

Soustraction
------------

La soustraction étant une addition « à l'envers », il semblerait qu'il
n'y ait pas plus  à dire à son sujet qu'au  sujet de l'addition. C'est
faux.  Il   faut  d'abord  distinguer  la   soustraction  indépendante
(c'est-à-dire en dehors de toute  division) et la soustraction incluse
(calcul du reste intermédiaire dans une division). De plus, si je n'ai
pas  prévu  de  variante pour  l'addition,  il  y  en  a une  pour  la
soustraction,  la  variante avec  le  complément  à _b_,  ainsi  qu'on
l'apprend  en cours  de programmation  assembleur (complément  à 2  ou
complément à 16).

### Soustraction indépendante

Une soustraction  se fait en  une seule phase. Toutefois,  lorsque les
deux nombres  à soustraire  sont très  différents, on  peut distinguer
jusqu'à trois sous-phases. Prenons par exemple la soustraction

```
123450000012345
-       8867700
---------------
```

La première sous-phase correspond aux opérations sur les chiffres du nombre
bas. Cela correspond à l'image que l'on se fait de la soustraction.

```
123450000012345
-       8867700
---------------
        1144645
```

Il n'y a plus de chiffre dans le nombre bas, mais il reste une retenue
à traiter. On passe à la deuxième sous-phase.

```
123450000012345
-       8867700
---------------
    49991144645
```

Maintenant,  il n'y  a ni  retenue, ni  chiffre du  nombre du  bas. La
troisième sous-phase consiste donc  simplement à recopier les chiffres
restants du nombre du haut.

```
123450000012345
-       8867700
---------------
123449991144645
```

Dans certains cas,  la deuxième sous-phase et  la troisième sous-phase
peuvent être absentes. Notamment, pour les soustractions permettant de
calculer le reste intermédiaire dans une division ou une extraction de
racine carrée, la seconde sous-phase  concernera au maximum un chiffre
du nombre du haut et la troisième sous-phase sera réduite à néant.

### Soustraction incluse dans un autre calcul

Prenons l'exemple de la division

```
---
9212|139
    |---
    |6
```

Lorsque  l'élève  calcule  le  reste intermédiaire,  il  commence  par
calculer  « 6 fois  9, 54 ».  Puis il  compare ce  produit 54  avec le
chiffre 1. L'élève  prononce alors « et 7, 61 » (ou  bien « ôté de 61,
reste 7 ») et « je pose 7, je retiens 6 »

Que  se  passe-t-il   en  réalité ?  Les  données  en   entrée  de  la
soustraction sont :

* un nombre « haut » à un seul chiffre (1 dans l'exemple), que vous
pouvez interpréter comme un nombre partiellement connu « ?1 »,

* un nombre « bas » à un ou deux chiffres (54 dans l'exemple).

Les données en sortie sont :

* un nombre  « haut » habituellement ajusté  à deux chiffres  (61 dans
l'exemple),

* le résultat de la soustraction, un seul chiffre (7 dans l'exemple).

Ce processus est un processus mental,  sans trace écrite, donc il fait
partie  de  la  classe  `Arithmetic::PaperAndPencil::Number`.  Il  est
utilisé également dans  la soustraction indépendante, même  si dans ce
cas on sait d'avance que la retenue ne peut pas dépasser `1`.

Une remarque annexe. Lorsque j'ai appris l'arithmétique dans mon jeune
âge, j'ai  appris à dire  « 6 fois  9, 54, et  7, 61 » alors  que dans
d'autres écoles, c'était plutôt « 6 fois  9, 54, ôté de 61, reste 7 ».
À  vrai dire,  je n'ai  pas compris  et je  ne comprends  toujours pas
pourquoi la  version que  j'ai apprise est  censée être  meilleure que
l'autre version. Peu importe, au final le message implémenté est celui
que j'ai appris. Pour les  autres langues, anglais, italien, espagnol,
etc.,  je   fais  confiance  à   quiconque  me  donnera   les  phrases
conventionnelles dans sa langue maternelle.

### Soustraction utilisant le complément à _b_

Cette variante est utilisé pour  la partie fractionnaire (ou mantisse)
des  logarithmes et  pour la  soustraction en  base 2  et en  base 16.
Pourtant, elle fonctionne avec les  entiers dans n'importe quelle base
de numération. Je  donnerai l'exemple en décimal avec  le complément à
10. Je reprends la soustraction de l'exemple ci-dessus.

```
123450000012345
-       8867700
---------------
```

Pour calculer  la différence, on  prend le complément à  10 (puisqu'on
est  en décimal)  du nombre  du bas.  En fait,  il n'y  a pas  un seul
complément  à 10,  il y  en a  plusieurs, en  fonction de  la longueur
souhaitée. Lors de calculs de logarithmes avec 5 décimales, ou lorsque
l'on écrit des  programmes assembleurs pour une machine à  16 bits, le
contexte  nous impose  une  longueur pour  le complément  à  10 ou  le
complément à 2, donc  la question est éludée. Ici le  nombre du haut a
15 chiffres, donc  on prend le complément à 10  de 8866700 de longueur
15. Il y a deux façons de le calculer.

Première façon : on  complète le nombre par des zéros  pour obtenir la
longueur souhaitée (15 dans l'exemple).

```
        8867700
000000008867700
```

On examine les chiffres en partant de la droite. Tant qu'il y a des
zéros, on les laisse tels quels.

```
000000008867700
             00
```

Le chiffre  suivant, et  uniquement ce chiffre,  est remplacé  par son
complément à 10. Dans l'exemple, 7 devient 3.

```
000000008867700
            300
```

Enfin on remplace  tous les chiffres restants par leur  complément à 9
(y compris les zéros restants). Dans l'exemple, 7 devient 2, 6 devient
3, 8 devient 1 et 0 devient 9.

```
000000008867700
999999991132300
```

Deuxième façon de calculer le complément  à 10 : on complète le nombre
par des zéros pour obtenir la longueur souhaitée.

```
        8867700
000000008867700
```

On remplace tous les chiffres, sans exception, par leur complément à 9.

```
000000008867700
999999991132299
```

Et on ajoute 1.

```
000000008867700
999999991132299
              1
---------------
999999991132300
```

Une fois que l'on a obtenu le complément  à 10 du nombre du bas par la
première ou la deuxième méthode, on l'additionne au nombre du haut.

```
 123450000012345
 999999991132300
----------------
1123449991144645
```

Il  y  a forcément  un  chiffre  supplémentaire  (qui fait  passer  le
résultat à  16 chiffres dans  l'exemple) et ce  chiffre supplémentaire
est forcément  1. On supprime  ce chiffre  et on obtient  le résultat,
123449991144645.

Bien sûr, en base 2 on parlera du complément à 1 et du complément à 2.
En base 16, on peut parler du  complément à 15 (ou F) et du complément
à 16,  mais comme la  base 16 est, en  quelque sorte, une  « vision de
haut-niveau » de  la base 2,  il arrive  fréquemment que, par  abus de
langage, on parle de complément à 1 et de complément à 2 en base 16.

Multiplication
--------------

### Standard

La multiplication standard est la multiplication bien connue

```
   628
   234
  ----
  2512
 1884.
1256..
------
146952
```

Y a-t-il quelque chose à ajouter ? Oui. Il y a deux sous-variantes. La
première  est la  sous-variante « avec  raccourcis ». Si,  au lieu  de
multiplier 628 par 234, on le  multiplie par 333, la variante standard
basique effectue trois fois le même calcul, ce qui donne :

```
3 fois 8, 24, je pose 4 et je retiens 2
3 fois 2, 6, et 2, 8, je pose 8 et je ne retiens rien
3 fois 6, 18, je pose 18

   628
   333
  ----
  1884

3 fois 8, 24, je pose 4 et je retiens 2
3 fois 2, 6, et 2, 8, je pose 8 et je ne retiens rien
3 fois 6, 18, je pose 18

   628
   333
  ----
  1884
 1884.

3 fois 8, 24, je pose 4 et je retiens 2
3 fois 2, 6, et 2, 8, je pose 8 et je ne retiens rien
3 fois 6, 18, je pose 18

   628
   333
  ----
  1884
 1884.
1884..
```

Dans la variante avec raccourcis, ces calculs sont effectués une seule
fois. Les deux autres fois, le calculateur se contente de recopier une
ligne existante, ce qui donne