From d4578705f135c332f8be53e89baf508a8bd4e13e Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Thu, 16 Dec 2010 23:58:18 +0000 Subject: xlop 0.23 (17dec10) git-svn-id: svn://tug.org/texlive/trunk@20769 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/generic/xlop/LISEZ.MOI | 8 +- Master/texmf-dist/doc/generic/xlop/READ.ME | 51 + Master/texmf-dist/doc/generic/xlop/README | 49 - Master/texmf-dist/doc/generic/xlop/XLOP03 | 35 - Master/texmf-dist/doc/generic/xlop/fr-user.pdf | Bin 283832 -> 0 bytes Master/texmf-dist/doc/generic/xlop/fr-user.tex | 2387 ------------------- Master/texmf-dist/doc/generic/xlop/history.txt | 7 +- Master/texmf-dist/doc/generic/xlop/xlop-doc-fr.pdf | Bin 0 -> 336088 bytes Master/texmf-dist/doc/generic/xlop/xlop-doc-fr.tex | 2424 ++++++++++++++++++++ Master/texmf-dist/doc/generic/xlop/xlop-doc.pdf | Bin 0 -> 317393 bytes Master/texmf-dist/doc/generic/xlop/xlop-doc.tex | 2271 ++++++++++++++++++ Master/texmf-dist/source/generic/xlop/manual.sty | 7 +- Master/texmf-dist/tex/generic/xlop/xlop.sty | 2 +- Master/texmf-dist/tex/generic/xlop/xlop.tex | 1896 +++++++-------- 14 files changed, 5756 insertions(+), 3381 deletions(-) create mode 100644 Master/texmf-dist/doc/generic/xlop/READ.ME delete mode 100644 Master/texmf-dist/doc/generic/xlop/README delete mode 100644 Master/texmf-dist/doc/generic/xlop/XLOP03 delete mode 100644 Master/texmf-dist/doc/generic/xlop/fr-user.pdf delete mode 100644 Master/texmf-dist/doc/generic/xlop/fr-user.tex create mode 100644 Master/texmf-dist/doc/generic/xlop/xlop-doc-fr.pdf create mode 100644 Master/texmf-dist/doc/generic/xlop/xlop-doc-fr.tex create mode 100644 Master/texmf-dist/doc/generic/xlop/xlop-doc.pdf create mode 100644 Master/texmf-dist/doc/generic/xlop/xlop-doc.tex (limited to 'Master') diff --git a/Master/texmf-dist/doc/generic/xlop/LISEZ.MOI b/Master/texmf-dist/doc/generic/xlop/LISEZ.MOI index 01be2e2d666..ae96e144eac 100644 --- a/Master/texmf-dist/doc/generic/xlop/LISEZ.MOI +++ b/Master/texmf-dist/doc/generic/xlop/LISEZ.MOI @@ -31,12 +31,14 @@ Installation ------------ L'extension étant prévue pour pouvoir fonctionner aussi bien sous TeX que sous LaTeX, les recommandations de la TDS indiquent que l'endroit -le plus correct pour placer ces fichiers (xlop.tex et xlop.sty) est : -[texmf]/tex/generic/xlop/. +le plus correct pour placer le fichier xlop.tex est + [texmf]/tex/generic/xlop/ +et celui pour placer le fichier xlop.sty est + [texmf]/tex/latex/xlop/ Il reste les fichiers de documentation (LISEZ.MOI, README, history.txt, manual.sty et fr-user.*). Leur place normale devrait -être [texmf]/doc/generic/xlop/. +être [texmf]/doc/xlop/. Il reste à rafraichir la base en lançant la commande texhash (ou mktexlsr, ou ...) et tout devrait être opérationnel. diff --git a/Master/texmf-dist/doc/generic/xlop/READ.ME b/Master/texmf-dist/doc/generic/xlop/READ.ME new file mode 100644 index 00000000000..83b40a26c55 --- /dev/null +++ b/Master/texmf-dist/doc/generic/xlop/READ.ME @@ -0,0 +1,51 @@ +OVERVIEW +-------- +Package xlop proposes two main features. First, xlop prints +operations (displayed or running), that is, user write only +operands. Second, xlop is able to deal with unlimited numbers, in +fact, limitations are due to TeX memory. This features include +basic arithmetic operations, input/ouput, numeric variables, tests, +and some high level operation (without operations which imply infinite +processing such roots, exponential, trigonometric functions, etc.). + +DISTRIBUTION +------------ +Contents +-------- +Distribution consists of files: + * README (the file you are reading) + * LISEZ.MOI (same in french) + * XLOP03 indicates what features the next version should be provide + * history.txt relates project history + * manual.sty package file to compile fr-user.tex + * fr-user.tex xlop user's manual input file + * fr-user.pdf xlop user's manual + * xlop.tex xlop code + * xlop.sty allow the use of xlop as LaTeX package + +Installation +------------ +xlop can be used under TeX or LaTeX. Thus, TDS recommendations are +that the best place to put the file xlop.tex is + [texmf]/tex/generic/xlop/ +and that the best place to put xlop xlop.sty is + [texmf]/tex/latex/xlop/ + +For documentation files (README, history.txt, manual.sty, and +fr-user.*), best place should be [texmf]/doc/generic/xlop/. + +You have just to run texhash command (or mktexlsr, or ...) to refresh +your texmf base and all should work fine. + +BUGS AND TROUBLES +----------------------------- +If you detect some bug, whatever its seriousness (that could be just +spurious spaces), try to illustre this error with an example as short +as possible. Particularly, don't use unecessary package. Sent your +code with a short explanation at: + +Jean-Come.Charpentier@wanadoo.fr + +If you wish for some feature in a future version, ask to the author. +To help my antispam soft, could you please write 'xlop' in the message +subject? diff --git a/Master/texmf-dist/doc/generic/xlop/README b/Master/texmf-dist/doc/generic/xlop/README deleted file mode 100644 index c87c71c828a..00000000000 --- a/Master/texmf-dist/doc/generic/xlop/README +++ /dev/null @@ -1,49 +0,0 @@ -OVERVIEW --------- -Package xlop proposes two main features. First, xlop prints -operations (displayed or running), that is, user write only -operands. Second, xlop is able to deal with unlimited numbers, in -fact, limitations are due to TeX memory. This features include -basic arithmetic operations, input/ouput, numeric variables, tests, -and some high level operation (without operations which imply infinite -processing such roots, exponential, trigonometric functions, etc.). - -DISTRIBUTION ------------- -Contents --------- -Distribution consists of files: - * README (the file you are reading) - * LISEZ.MOI (same in french) - * XLOP03 indicates what features the next version should be provide - * history.txt relates project history - * manual.sty package file to compile fr-user.tex - * fr-user.tex xlop user's manual input file - * fr-user.pdf xlop user's manual - * xlop.tex xlop code - * xlop.sty allow the use of xlop as LaTeX package - -Installation ------------- -xlop can be used under TeX or LaTeX. Thus, TDS recommendations are -that the best place to put files (xlop.tex and xlop.sty) is -[texmf]/tex/generic/xlop/. - -For documentation files (README, history.txt, manual.sty, and -fr-user.*), best place should be [texmf]/doc/generic/xlop/. - -You have just to run texhash command (or mktexlsr, or ...) to refresh -your texmf base and all should work fine. - -BUGS AND TROUBLES ------------------------------ -If you detect some bug, whatever its seriousness (that could be just -spurious spaces), try to illustre this error with an example as short -as possible. Particularly, don't use unecessary package. Sent your -code with a short explanation at: - -Jean-Come.Charpentier@wanadoo.fr - -If you wish for some feature in a future version, ask to the author. -To help my antispam soft, could you please write 'xlop' in the message -subject? diff --git a/Master/texmf-dist/doc/generic/xlop/XLOP03 b/Master/texmf-dist/doc/generic/xlop/XLOP03 deleted file mode 100644 index b742723029a..00000000000 --- a/Master/texmf-dist/doc/generic/xlop/XLOP03 +++ /dev/null @@ -1,35 +0,0 @@ -xlop is still under construction. In fact, xlop 0.2 is just a beta -release; xlop 0.3 will provide: - - * Full redefinition about internal number representation (faster - and less memory space). - * Some macros improved (\opprint, \opdisplay, \opput, ...). - * New parameters (format=normal/sci/eng, carrymul, - hyphen (multiline for very long numbers), fine division and - multiplication control, ...) - * Calculation on basis 2 to 36 - e.g. \opadd[style=text]{"2"11010}{"2"10010} will display - 11010 + 10010 = 101100 - * Support language (languages defined in babel, oldrussian, and - babylon) e.g. \div[displayintermediary=all]{33}{2} displays - - language= french english - - 33 | 2 16.5 - -2 |--- ______ - --- | 16,5 2 ) 33 - 13 | 20 - -12 | -- - ---- | 13 - 10 | 12 - -10 | ---- - --- | 1.0 - 0 | 1.0 - --- - 0 - Language define decimal separator, thousand separator, type of - displayed multiplication, type of displayed division (Author knows - 3 types of multiplications and 2 types of divisions) . - * High level functions (exp, log, sin, asin, sinh, argsin, (idem - for cos, tan, and cot), sqrt, root). - * last but not least, english documentation! diff --git a/Master/texmf-dist/doc/generic/xlop/fr-user.pdf b/Master/texmf-dist/doc/generic/xlop/fr-user.pdf deleted file mode 100644 index 4e30e3edc6c..00000000000 Binary files a/Master/texmf-dist/doc/generic/xlop/fr-user.pdf and /dev/null differ diff --git a/Master/texmf-dist/doc/generic/xlop/fr-user.tex b/Master/texmf-dist/doc/generic/xlop/fr-user.tex deleted file mode 100644 index 9a8a37be4fc..00000000000 --- a/Master/texmf-dist/doc/generic/xlop/fr-user.tex +++ /dev/null @@ -1,2387 +0,0 @@ -\documentclass[12pt]{report} -\usepackage{manual} -\usepackage[frenchb]{babel} -\fvset{label=source}% français - -\begin{document} -\begin{titlepage} - \null\par\vfill - \begin{center} - \begin{minipage}{0.75\linewidth} - \hrule width\linewidth height2pt depth0pt - \hrule width0pt height3pt depth0pt - \hrule width\linewidth height1pt depth0pt - \hrule width0pt height18pt depth0pt - \begin{center} - \Huge\bfseries XLOP v \fileversion\par\vskip18pt - Manuel de l'utilisateur - \end{center} - \hrule width0pt height6pt depth0pt - \hrule width\linewidth height1pt depth0pt - \hrule width0pt height3pt depth0pt - \hrule width\linewidth height2pt depth0pt - \end{minipage} - \end{center} - \vfill - \begin{center} - Jean-Côme Charpentier\\ - \today - \end{center} - \vfill\null\par -\end{titlepage} -\newpage -\pagenumbering{roman} -\tableofcontents -\newpage -\pagenumbering{arabic} - -\chapter{Présentation} -\label{chap:Présentation} -L'extension \package{xlop} a été développée pour permettre de réaliser -automatiquement des calculs arithmétiques sur des nombres de taille -quelconque et d'afficher les résultats sous forme posée ou en -ligne. Voici un premier exemple permettant de donner un aperçu de la -syntaxe de base : -\begin{SideBySideExample} - \opadd{45,05}{78,4} -\end{SideBySideExample} -Ce premier exemple appelle quelques commentaires qui permettront de -donner une idée sur la façon de manipuler l'extension. - -L'addition est posée \og comme à l'école \fg{} : il s'agit de la -présentation par défaut. On a un alignement sur la virgule des -opérandes et du résultat, le symbole opératoire placé à gauche est -centrée verticalement entre les deux opérandes et le séparateur -décimal est un point malgré le fait d'avoir indiquer les opérandes -avec une virgule dans l'appel de la macro. Enfin, on notera la -présence d'une retenue au dessus de la première opérande. - -Mis à part l'alignement sur la virgule qui est obligatoire pour -l'addition posée, toutes les autres caractéristiques décrites -ci-dessus sont paramétrables. Certaines macros de l'extension et, en -tout cas, toutes les macros affichant les opérations arithmétiques -admettent un argument optionnel qui permettra de contrôler la -présentation. Pour cela, on utilisera une syntaxe \og à la keyval -\fg{} : on spécifie une suite de modifications de paramètres par une -liste d'affectations séparées par des virgules. Une affectation a -une des deux syntaxes possibles ci-dessous : -\begin{verbatim} - = - -\end{verbatim} -la seconde possibilité étant en fait un raccourci pour : -\begin{verbatim} - =true -\end{verbatim} -Dans cette liste d'affectation, on peut faire suivre les virgules par -un ou plusieurs espaces mais il ne faut pas mettre d'espace de part et -d'autre du signe égal ou avant la virgule : un paramètre ou une valeur -pouvant (potentiellement) comporter le caractère espace. - -Ainsi, si l'on veut un séparateur décimal qui soit une virgule, un -symbole opératoire placé en face de la seconde opérande et en -supprimant la présence des retenues, il suffit d'indiquer : -\begin{SideBySideExample} - \opadd[decimalsepsymbol={,}, - voperator=bottom, - carryadd=false]{45.05}{78.4} -\end{SideBySideExample} -On notera la petite astuce consistant à mettre la virgule entre -accolades dans la définition du symbole du séparateur décimal. En -effet, la syntaxe : -\begin{Verbatim}[xrightmargin=0pt] - \opadd[decimalsepsymbol=,,voperator=bottom, - carryadd=false]{45.05}{78.4} -\end{Verbatim} -est fautive : \package{xlop} ne comprenant plus trop bien ce qu'est -cette \og liste \fg{} ! - -Un autre point important quoique moins visible, est que les chiffres -sont disposés à des emplacements très précis. Chaque chiffre est placé -dans une boîte de largeur et de hauteur fixes (paramétrables), le -séparateur décimal est, par défaut, placé dans une boîte de largeur -nulle et toutes les lignes sont régulièrement espacées qu'il y ait ou -non un trait horizontal. Cela permet d'obtenir des alignements -rigoureux et permet également de placer ce que l'on veut à -l'emplacement que l'on veut. -\begin{SideBySideExample} - \psset{xunit=\opcolumnwidth, - yunit=\oplineheight} - \opadd{45.05}{78.4} - \oplput(1.5,3){retenue} - \psline{->}(1,3.15)(-3.25,3.15) -\end{SideBySideExample} -Cet exemple a été réalisé en utilisant l'extension -\package{pstricks}\index{pstricks@\package{pstricks}} - -Nous avons dit précédemment que \package{xlop} était capable de -manipuler des nombres de taille quelconque. Nous reviendrons plus en -détail sur cette possibilité et nous nous contenterons ici de ne donner -qu'un exemple de ce que cela peut offrir. Ne regardez pas trop le -code, les explications seront données plus loin dans ce manuel, pour -l'instant, admirez seulement le résultat ! -\begin{CenterExample}[xrightmargin=0pt] - \opdiv[style=text,period]{1}{49} -\end{CenterExample} - -L'extension \package{xlop} offre quelques autres fonctionnalités. Il -est ainsi possible de manipuler les nombres par l'intermédiaire de -variables, ces variables pouvant être créées par une assignation -simple ou bien comme résultat d'un calcul. On peut également manipuler -les chiffres de façon individuelle : -\begin{SideBySideExample} - \opadd*{45.05}{78.4}{r}% - Le premier chiffre après la virgule de - $45.05+78.4$ est un - \opgetdecimaldigit{r}{1}{d}% - $\opprint{d}$. -\end{SideBySideExample} -effectuer des tests : -\begin{SideBySideExample} - \opadd*{45.05}{78.4}{r}% - La somme $45.05+78.4$ est - \opcmp{r}{100}% - \ifopgt strictement supérieure - \else\ifoplt strictement inférieure - \else égale - \fi\fi - à $100$. -\end{SideBySideExample} -avoir accès à quelques opérations ou fonctions : -\begin{SideBySideExample} - Le pgcd de $182$ et $442$ est - \opgcd{182}{442}{d}$\opprint{d}$ -\end{SideBySideExample} -pouvoir réaliser des calculs complexes sous forme infixe : -\begin{SideBySideExample} - \opexpr{(2+3^2)/(gcd(22,33))}{r}% - $$\frac{2+3^2}{\gcd(22,33)} = - \opprint{r}$$ -\end{SideBySideExample} - -\chapter{Instruction \package{xlop}} -\`A quelques exceptions près qui seront étudiées en temps voulu, les -macros de \package{xlop} peuvent éventuellement avoir un argument -optionnel entre crochets pour modifier localement la valeur des -paramètres de fonctionnement, les autres arguments (obligatoires) -étant des nombres. Les deux sections de ce chapitre décrivent en -détail ce qu'est un nombre pour \package{xlop} et comment se servir -de ses paramètres. - -\section{Au début était le nombre} -\label{sec:Au début etait le nombre} -\subsection{Taille} -\label{subsec:Taille} -Avant de voir la syntaxe générale d'un nombre, nous allons nous -pencher sur la particularité de \package{xlop} qui est de pouvoir -manipuler des nombres de taille quelconque. - -\index{nombre!taille}Pour être tout à fait précis, la taille théorique -maximum d'un nombre est de $2^{31}-1$ chiffres. En pratique, cette -limite ne pourra pas être atteinte pour deux raisons essentielles. La -première est qu'une multiplication avec deux opérandes ayant $2^{25}$ -chiffres demanderait plus de $7\,000$ années de calcul sur -l'ordinateur de l'auteur ! La seconde est beaucoup plus restrictive -car elle est liée aux limites de taille des piles de \TeX{}. Voici un -tableau indiquant une compilation sous \TeX{} avec une multiplication -de deux opérandes de même taille sur une machine Linux, pentium~II~600 -et 256~Mo de RAM : -\begin{center} - \begin{tabular}{|l|*{6}{c|}} - \hline - nombre de chiffres & 100 & 200 & 300 & 400 & 425 & 450 \\\hline - temps de compilation (s) & 2 & 8 & 18 & 32 & 36 & crash \\\hline - \end{tabular} -\end{center} -Le \og crash \fg{} indiqué dans le tableau est dû au débordement de la -table de hachage (hash table). -\index{hash table}% -\index{depassement de capacite@dépassement de capacité}% -Sous \LaTeX{}, la limite avant crash sera plus réduite. D'autre part, -ces tests ont été effectués sur un fichier minimum : avec un document -source classique, cette limite sera un peu plus basse. Une autre -limite qui risque d'être atteinte relativement rapidement est la -taille du spouleur (spool size). -\index{spool size}% -Pour composer ce document qui contient un grand nombre d'appel aux -macros de \package{xlop}, l'auteur a augmenté la taille du spouleur -à~$250\,000$ ($125\,000$ s'étant révélé insuffisante) en éditant la -ligne \verb+pool_size+ du fichier \file{texmf.cnf}. De même, la table -de hachage a dû être augmentée en stipulant la valeur \texttt{1000} au -niveau de la ligne \verb+hash_extra+ du fichier \file{texmf.cnf}. - -\subsection{Syntaxe} -\label{subsec:Syntaxe} -Nous allons présenter cette syntaxe avec la grammaire BNF mais des -explications plus humaines suivront : -\begin{syntaxBNF} - \*nombre* & \{\*signe*\}\*nombre_positif* \alt \*nom* \\ - \*signe* & + \alt - \\ - \*nombre_positif* & \*entier* \alt \*sep*\*entier* \alt \\ - \sameline \*entier*\*sep* \alt \*entier*\*sep*\*entier* \\ - \*sep* & . \alt , \\ - \*entier* & \*chiffre*\{\*chiffre*\} \\ - \*nom* & \*début*\{caractère\} \\ - \*début* & caractère \textnormal{autre que } \*signe*\textnormal{,} - \*sep* \\ - \sameline \textnormal{et} \*chiffre* -\end{syntaxBNF} - -Le symbole \texttt{caractère} désigne presque n'importe quel caractère -accepté par \TeX{}. Les seules exceptions sont les caractères \verb+%+, -et \verb+#+ qui sont totalement interdits. En fait, les caractères -actifs risquent de poser des problèmes. Par exemple, la définition de -\verb+~+ sous \LaTeX{} empêche ce caractère de pouvoir faire partie -d'un nom. D'autre part, le caractère \verb+\ +conserve sont rôle de -caractère d'échappement, c'est-à-dire que le nom sera celui obtenu -après développement de la macro introduite. Il n'y a aucune autre -contrainte comme le montre le code suivant : -\begin{SideBySideExample} - \newcommand\prefix{a/b} - \opadd*{2}{2}{a/b_{^c}!&$} - \opprint{\prefix_{^c}!&$} -\end{SideBySideExample} -On notera en particulier que \verb+a/b_{^c}!&$+ et -\verb+\prefix_{^c}!&$+ représentent exactement le même nom, si -\verb+\prefix+ a la définition adéquate évidemment. Cette possibilité -d'obtenir un nom en utilisant des macros peut sembler inutile mais il -n'en est rien. On peut ainsi réaliser des boucles avec des noms tels -que \verb+r1+, \verb+r2+, \ldots, \verb+r+ en utilisant le code -\verb+r\the\cpt+ comme nom où \verb+cpt+ est un compteur (au sens -\TeX{}, le mécanisme des compteurs avec \LaTeX{} empêche d'être aussi -flexible). Nous verrons un exemple d'utilisation de cette forme à la -section~\ref{sec:Creation d'operations complexes} -page~\pageref{sec:Creation d'operations complexes}. - -\index{nombre!valide}En pratique, que signifient toutes ces règles ? -Elles indiquent d'abord qu'un nombre écrit sous forme décimale peut -être précédé par n'importe quelle séquence de signes plus et moins. -Évidemment, le nombre sera négatif lorsqu'il y aura un nombre impair -de signes moins. Ensuite, un nombre ne peut comporter qu'un seul -séparateur décimal qui peut être le point ou la virgule, celui-ci -pouvant être placé n'importe où dans le nombre. Enfin, l'écriture d'un -nombre s'effectue obligatoirement en base~10. Attention : ces règles -signifient également que \verb+-a+ n'est pas valide. - -L'extension utilise quelques noms de façon interne et il est plus -prudent de ne pas commencer un nom de variable par le caractère -\texttt{@}. - -\section{Paramètres de \package{xlop}} -\label{sec:Parametres de xlop} -\index{parametre@paramètre!syntaxe|(} -Les affectations de paramètres restent locales à la macro lorsqu'elles -sont indiquées au niveau de son argument optionnel. Pour rendre de -telles affectations globales, il faut utiliser la macro -\macro{opset}. Par exemple -\begin{Verbatim}[xrightmargin=0pt] - \opset{decimalsepsymbol={,}} -\end{Verbatim} -fera que le symbole du séparateur décimal sera la virgule pour tout le -reste du document, ou, du moins, jusqu'à une prochaine redéfinition -par la macro \verb+\opset+. Dans ce manuel, ce sera le cas à partir de -maintenant.\opset{decimalsepsymbol={,}} - -\subsection{Symboles} -\label{subsecSymboles} -Le paramètre \parameter{afterperiodsymbol} indique le symbole qui -suit l'écriture d'un quotient en ligne lors d'une division avec -recherche de période. Sa valeur par défaut est \verb+$\ldots$+ - -Le paramètre \parameter{equalsymbol} indique le symbole utilisé pour -l'égalité. Sa valeur par défaut est \verb+$=$+. En réalité, le -paramètre est défini avec : -\begin{Verbatim}[xrightmargin=0pt] - \opset{equalsymbol={$=$}} -\end{Verbatim} -c'est-à-dire avec des accolades pour protéger le signe égal. Sans les -accolades, il y aurait une erreur à la compilation. On doit procéder -de cette façon lorsque la valeur comporte le signe égal ou une -virgule\index{parametre@paramètre!avec \og = \fg{} ou \og ,\fg} - -Le paramètre \parameter{approxsymbol} indique le symbole utilisé pour -les approximations. Sa valeur par défaut est \verb+$\approx$+. - -Le paramètre \parameter{decimalsepsymbol} indique le symbole utilisé -pour le séparateur décimal. Sa valeur par défaut est le point. - -Les paramètres \parameter{addsymbol}, \parameter{subsymbol}, -\parameter{mulsymbol} et \parameter{divsymbol} indiquent les symboles -utilisés pour les quatre opérations arithmétiques. Les valeurs par -défaut sont respectivement \verb!$+$!, \verb!$-$!, \verb!$\times$! et -\verb!$\div$!. - -\subsection{Présentation générale} -\label{subsec:Presentation generale} -Le paramètre \parameter{voperation} indique la façon dont une -opération posée sera placée par rapport à la ligne de base. Les -valeurs possibles sont \verb+top+, \verb+center+ et \verb+bottom+ -(valeur par défaut). -\begin{SideBySideExample} - top\quad - \opadd[voperation=top]{45}{172}\par - center\quad - \opadd[voperation=center]{45}{172}\par - bottom\quad - \opadd[voperation=bottom]{45}{172} -\end{SideBySideExample} - -Le paramètre \parameter{voperator} indique comment sera placé le -symbole opératoire par rapport aux opérandes. Les valeurs possibles -sont \verb+top+, \verb+center+ (valeur par défaut) et \verb+bottom+. -\begin{SideBySideExample} - top\quad - \opadd[voperator=top]{45}{172}\par - center\quad - \opadd[voperator=center]{45}{172}\par - bottom\quad - \opadd[voperator=bottom]{45}{172} -\end{SideBySideExample} - -Le paramètre \parameter{deletezero} indique si certains nombres d'une -opération doivent être affichés avec ou sans les zéros non -significatifs. Le rôle exact de ce paramètre varie en fonction de -l'opération et nous y reviendrons lors de la présentation des -différentes opérations. - -Le paramètre \parameter{style} indique si l'opération doit être posée -(valeur \verb+display+ qui est la valeur par défaut) ou bien être -affichée en ligne (valeur \verb+text+). On reviendra sur ce paramètre -lors de la présentation de la division car les possibilités sont alors -un peu plus nombreuses. -\begin{SideBySideExample} - \opadd[style=text]{45}{172} -\end{SideBySideExample} -Dans les opérations en ligne, \package{xlop} fait attention à ne pas -composer la formule en mode mathématique de façon directe. Cela permet -de spécifier ce que l'on veut comme dans l'exemple qui suit et c'est -également pour cela qu'il faut indiquer les valeurs classiques des -symboles entre délimiteurs mathématiques. -\begin{SideBySideExample} - \opadd[addsymbol=plus, - equalsymbol=\'egal, - style=text]{42}{172} -\end{SideBySideExample} -Cependant, \package{xlop} introduit exactement les mêmes pénalités de -coupures et exactement les mêmes espacements que pour une formule -mathématique. - -Le paramètre \parameter{parenthesisnegative} indique comment composer -les nombres négatifs dans les opérations en ligne. Les valeurs -possibles sont : -\begin{itemize} -\item \texttt{none} qui compose les nombres négatifs sans parenthèse ; -\item \texttt{all} qui compose les nombres négatifs en les plaçant - entre parenthèses ; -\item \texttt{last} qui compose les nombres négatifs en les plaçant - entre parenthèses s'il ne s'agit pas de la première opérande. -\end{itemize} -\begin{SideBySideExample} - \opadd[style=text, - parenthesisnegative=none] - {-12}{-23}\par - \opadd[style=text, - parenthesisnegative=all] - {-12}{-23}\par - \opadd[style=text, - parenthesisnegative=last] - {-12}{-23} -\end{SideBySideExample} - -\subsection{Dimensions} -\label{subsec:Dimensions} -Dans les opérations posées, les chiffres sont placés dans des boîtes -de dimensions fixées. La largeur est donnée par le paramètre -\parameter{columnwidth} et la hauteur par le paramètre -\parameter{lineheight}. La valeur par défaut de \texttt{lineheight} -est \verb+\baselineskip+ ce qui fait que les lignes des opérations -seront espacées, par défaut, comme les lignes d'un paragraphe. La -valeur par défaut de \texttt{columnwidth} est de \texttt{2ex} car la -largeur \og normale \fg{} des chiffres aurait donné des résultats peu -lisibles. -\begin{SideBySideExample} - \opadd[columnwidth=0.5em] - {45.89}{127.5} -\end{SideBySideExample} -Ce piètre résultat est dû en partie au fait que la virgule est placé -dans une boîte dont la largeur est contrôlée par le paramètre -\parameter{decimalsepwidth} dont la valeur par défaut est nulle. Un -essai d'amélioration peut être effectué en donnant à ce paramètre la -largeur \fg{} normale \og d'une virgule. -\begin{SideBySideExample} - \opadd[columnwidth=0.5em, - decimalsepwidth=0.27778em] - {45.89}{127.5} -\end{SideBySideExample} -C'est meilleur mais le fait de donner une largeur non nulle à la boîte -contenant le séparateur décimal risque de poser des difficultés si -l'on veut placer des éléments externes : cela va à l'encontre de -l'idée de placer les chiffres dans une grille fixe. Ceci est donc à -éviter en temps normal. - -Les deux paramètres \parameter{columnwidth} et \parameter{lineheight} -correspondent aux deux seules dimensions que l'extension rend -publiques, à savoir respectivement -\verb+\opcolumnwidth+\index{opcolumnwidth@\texttt{$\backslash$opcolumnwidth}} -et -\verb+\oplineheight+\index{oplineheight@\texttt{$\backslash$oplineheight}}. -Il est cependant dangereux de vouloir modifier ces dimensions de façon -directe puisque une modification par voie normale n'a pas pour seule -conséquence d'obtenir une nouvelle valeur pour ces -dimensions. L'extension \package{xlop} a rendu ces dimensions -publiques uniquement pour pouvoir les lire, pas pour les modifier. - -Les deux paramètres suivants permettent de spécifier les largeurs des -traits horizontaux et verticaux tracés par \package{xlop}. Il s'agit -des paramètres \parameter{hrulewidth} et \parameter{vrulewidth} dont -la valeur par défaut est \texttt{0.4pt}. - -Ces traits sont composés sans perturber la grille, c'est-à-dire sans -ajouter d'espace vertical. Ainsi, avec des valeurs importantes pour -l'épaisseur, les traits risquent de déborder au niveau des opérandes. -\begin{SideBySideExample} - \opadd[hrulewidth=8pt]{42}{172} -\end{SideBySideExample} - -Il existe également un paramètre permettant de contrôler le décalage -horizontal du séparateur décimal. Il s'agit de -\parameter{decimalsepoffset} dont la valeur par défaut est égale -à~\texttt{-0.35}. Cette valeur par défaut indique une longueur en -prenant \verb+\opcolumnwidth+ comme unité. Un exemple d'utilisation de -ce paramètre sera donné à la section~\ref{sec:Division} -page~\pageref{sec:Division}. - -\subsection{Styles des chiffres} -\label{subsec:Styles des chiffres} -L'extension \package{xlop} distingue cinq types de nombres et y -associe cinq paramètres de style : -\begin{itemize} -\item les opérandes avec \parameter{operandstyle} ; -\item le résultat avec \parameter{resultstyle} ; -\item les restes avec \parameter{remainderstyle} ; -\item les résultats intermédiaires avec \parameter{intermediarystyle} - ; -\item les retenues avec \parameter{carrystyle}. -\end{itemize} -\begin{SideBySideExample} - \opadd[operandstyle=\blue, - resultstyle=\red, - carrystyle=\scriptsize\green] - {45.89}{127.5} -\end{SideBySideExample} -Rappelons que dans ce manuel, nous utilisons l'extension -\package{pstricks}\index{pstricks}. - -\index{parametre@paramètre!indexé|(}% -En réalité, la gestion de ces styles est encore plus puissante car on -peut distinguer les différents nombres d'une même classe. Dans une -même opération, on a plusieurs opérandes et, éventuellement plusieurs -restes et plusieurs nombres intermédiaires. On accède alors au style -de ces nombres individuels en indexant le paramètre de style -correspondant. -\begin{SideBySideExample} - \opadd[operandstyle=\blue, - operandstyle.1=\lightgray, - resultstyle=\red, - carrystyle=\scriptsize\green] - {45.89}{127.5} -\end{SideBySideExample} -Sur cet exemple, on a indiqué que la première opérande devait être -composée avec le style \verb+\lightgray+ et comme rien n'était indiqué -pour la seconde opérande, celle-ci a repris le style de base de sa -classe (donc a été composée avec le style \verb+\blue+). - -Ce mécanisme va encore plus loin car on peut indicer à deux niveaux -les styles des classes opérande, reste et nombre intermédiaire et à un -niveau les styles des classes résultat et retenue pour accéder au -style de chacun des chiffres de ces nombres. Afin de rendre les -indexations plus facile à gérer, un index positif indiquera le rang -d'un chiffre de la partie entière (numérotée de droite à gauche, -l'index~1 correspondant au chiffre des unités) et un index négatif -indiquera le rang d'un chiffre de la partie décimale (numérotée de -gauche à droite, l'index $-1$ correspondant au chiffre des dixièmes). -\begin{SideBySideExample} - \opadd[operandstyle.1.1=\white, - operandstyle.1.-2=\white, - operandstyle.2.3=\white, - resultstyle.2=\white, - deletezero=false] - {045.89}{127.50} -\end{SideBySideExample} -On peut également utiliser une macro à un paramètre comme style. -\begin{SideBySideExample} - \newcommand\hole[1]{$\bullet$} - \opadd[operandstyle.1.1=\hole, - operandstyle.1.-2=\hole, - operandstyle.2.3=\hole, - resultstyle.2=\hole] - {45.89}{127.5} -\end{SideBySideExample} -Lorsque le style est une macro, le chiffre constitue le dernier -argument de cette macro. Voici un exemple plus compliqué et utilisant -l'extension \package{pst-node} de la suite \package{pstricks} : -\begin{SideBySideExample} - \newcommand\OPoval[3]{% - \dimen1=#2\opcolumnwidth - \ovalnode{#1} - {\kern\dimen1 #3\kern\dimen1}} - \opadd[voperation=top, - operandstyle.1.1=\OPoval{A}{0}, - operandstyle.2.2=\OPoval{C}{0.8}] - {45}{172}\qquad - \begin{minipage}[t]{2cm} - \pnode(0,0.2em){B}\ chiffre - \ncarc{->}{A}{B}\par - \pnode(0,0.2em){D}\ nombre - \ncarc{<-}{D}{C} - \end{minipage} -\end{SideBySideExample} - -Comme les chiffres, le séparateur décimal tient compte du style d'un -nombre. Pour accéder au style du séparateur décimal de façon -individuelle, il faut employer l'indice \texttt{d} au lieu des indices -numériques des chiffres. -\begin{SideBySideExample} - \newcommand\hole[1]{\texttt{\_}} - \opmul[intermediarystyle=\hole, - resultstyle=\hole, - resultstyle.d=\white]{2.46}{35.7} -\end{SideBySideExample} -\index{parametre@paramètre!indexé|)}% -\index{parametre@paramètre!syntaxe|)} - -\chapter{Opérations arithmétiques} -\label{chap:Opérations arithmétiques} -\section{Addition} -\label{sec:Addition} -L'addition est gérée par la macro \macro{opadd}. L'addition, -lorsqu'elle est posée, n'affiche que des nombres positifs. Cela va -avoir comme conséquence d'afficher une soustraction lorsqu'une des -opérandes est négative.% -\index{nombre!négatifs dans une opération posée} -\begin{SideBySideExample} - \opadd{-245}{72} -\end{SideBySideExample} -De façon générale, le principe est de poser l'opération qui permet de -retrouver le résultat comme on le ferait à la main. En revanche, -l'affichage en ligne donnera toujours une addition puisqu'on peut -maintenant écrire des nombres négatifs. -\begin{SideBySideExample} - \opadd[style=text]{-245}{72} -\end{SideBySideExample} - Outre les paramètres généraux décrits à la - section~\ref{sec:Parametres de xlop}, la macro \verb+\opadd+ est - sensible aux paramètres \texttt{carryadd}, \texttt{lastcarry} et - \texttt{deletezero}. - -Le paramètre \parameter{carryadd} est un paramètre -booléen\index{parametre@paramètre!booléen} c'est-à-dire n'acceptant -que les valeurs \texttt{true} et \texttt{false}. Comme il d'usage, -l'omission du signe égal et de la partie droite de l'affectation -équivaut à \texttt{=true}. Ce paramètre indique si les retenues -doivent être ou non affichées. Sa valeur par défaut est -\texttt{true}. - -Le paramètre \parameter{lastcarry} est également un paramètre -booléen. Il indique si une retenue sans chiffre correspondant au -niveau des deux opérandes doit être ou non affichée. Sa valeur par -défaut est \texttt{false}. On fera attention au rôle exact de ce -paramètre. Ainsi, si la seconde opérande dans l'exemple qui suit avait -été~15307, la dernière retenue aurait été affichée quelle que soit la -valeur du paramètre \texttt{lastcarry} puisqu'il y aurait eu un -chiffre correspondant au niveau de la seconde opérande. -\begin{SideBySideExample} - \opadd{4825}{5307} -\end{SideBySideExample} -\begin{SideBySideExample} - \opadd[carryadd=false]{4825}{5307} -\end{SideBySideExample} -\begin{SideBySideExample} - \opadd[lastcarry]{4825}{5307} -\end{SideBySideExample} - -Le paramètre \parameter{deletezero} est également un paramètre booléen -et son rôle et d'indiquer si les zéros non significatifs doivent être -supprimés ou non. Sa valeur par défaut est \texttt{true}. Si ce -paramètre vaut \texttt{false}, les opérandes et le résultats auront le -même nombre de chiffres, \package{xlop} ajoutant des zéros non -significatifs pour y parvenir. Les zéros non significatifs des -opérandes ne sont pas supprimés également. -\begin{SideBySideExample} - \opadd{012.3427}{5.2773}\par - \opadd[deletezero=false] - {012.3427}{5.2773} -\end{SideBySideExample} - -Ce paramètre a exactement le même rôle dans l'affichage en ligne que -dans l'affichage posé. -\begin{SideBySideExample} - \opadd[style=text]{02.8}{1.2}\par - \opadd[style=text, - deletezero=false]{02.8}{1.2}\par -\end{SideBySideExample} - -\section{Soustraction} -\label{sec:soustraction} -La soustraction est gérée par la macro \macro{opsub}. La soustraction, -lorsqu'elle est posée n'affiche que des nombres positifs. Cela va -avoir pour conséquence d'affficher une addition lorsqu'une des -opérandes est négative. -\begin{SideBySideExample} - \opsub{-245}{72} -\end{SideBySideExample} -De façon générale, le principe est de poser l'opération qui permet de -retrouver le résultat comme on le ferait à la main. En revanche, -l'affichage en ligne donnera toujours une soustraction puisqu'on peut -maintenant écrire des nombres négatifs. -\begin{SideBySideExample} - \opsub[style=text]{-245}{72} -\end{SideBySideExample} -Ce principe s'applique également lorsque la première opérande est -inférieure à la seconde (cas positif) où on aura une inversion des -opérandes. -\begin{SideBySideExample} - \opsub{1.2}{2.45} -\end{SideBySideExample} -Bien entendu, l'opération en ligne donnera le résultat exact. -\begin{SideBySideExample} - \opsub[style=text]{1.2}{2.45} -\end{SideBySideExample} - - -Outre les paramètres généraux vus à la section~\ref{sec:Parametres de - xlop}, \verb+\opsub+ est sensible aux paramètres -\texttt{carrysub}, \texttt{lastcarry}, \texttt{offsetcarry}, -\texttt{deletezero} et \texttt{behaviorsub}. - -Le paramètre \parameter{carrysub} est un paramètre booléen -qui indique si les retenues doivent être ou non présentes. Sa valeur -par défaut est \texttt{false} (rappelons que le paramètre -\texttt{carryadd} avait une valeur par défaut égale à \texttt{true}). -\begin{SideBySideExample} - \opsub[carrysub]{1234}{567} -\end{SideBySideExample} - -Dans l'exemple précédent, nous pouvons voir qu'il manque en fait une -retenue au niveau du dernier chiffre de 1234, cette façon de faire -étant assez courante. Néanmoins, on peut contrôler l'affichage de -cette dernière retenue avec le paramètre \parameter{lastcarry}. Ce -paramètre n'a pas tout à fait le même rôle que pour l'addition puisque -la dernière retenue ne sera pas affichée dans le cas où la seconde -opérande n'a pas de chiffre correspondant (alors que pour l'addition, -il fallait que les deux opérandes n'aient pas de chiffres -correspondant). -\begin{SideBySideExample} - \opsub[carrysub,lastcarry]{1234}{567} -\end{SideBySideExample} -On peut noter dans ce dernier cas qu'il est sans doute préférable de -mettre le paramètre \parameter{deletezero} à \texttt{false} pour -obtenir une présentation plus correcte. -\begin{SideBySideExample} - \opsub[carrysub, - lastcarry, - deletezero=false]{1234}{567} -\end{SideBySideExample} - -L'affichage des retenues au niveau des soustractions peut sembler un -peu trop compact. On peut élargir la boîte des chiffres avec le -paramètre \parameter{opcolumnwidth} mais également indiquer le -décalage des retenues avec le paramètre \parameter{offsetcarry}. La -valeur par défaut de ce paramètre est \texttt{-0.35}. -\begin{SideBySideExample} - \opsub[carrysub, - lastcarry, - deletezero=false]{12.34}{5.67} - - \bigskip - \opsub[carrysub, - lastcarry, - columnwidth=2.5ex, - offsetcarry=-0.4, - decimalsepoffset=-3pt, - deletezero=false]{12.34}{5.67} -\end{SideBySideExample} - -Il peut arriver qu'une soustraction de deux nombres positifs, le -premier étant inférieur au second, soit le signe d'une erreur de -l'utilisateur. Dans ce cas, et uniquement dans ce cas, le paramètre -\parameter{behaviorsub} permet d'obtenir un rappel à l'ordre. Les -trois valeurs possibles de ce paramètre sont \texttt{silent} qui est -la valeur par défaut et qui donne le résultat, \texttt{warning} qui -donne également le résultat mais affiche le message d'avertissement : -\begin{Verbatim}[xrightmargin=0pt,frame=none] - xlop warning. Substraction with first operand less than second one - See documentation for further information. -\end{Verbatim} -et enfin \texttt{error} qui affichera le message d'erreur : -\begin{Verbatim}[xrightmargin=0pt,frame=none] - xlop error. See documentation for further information. - Type H for immediate help. - ! Substraction with first operand less than second one. -\end{Verbatim} -et l'opération ne sera pas effectuée. - -\section{Multiplication} -\label{sec:Multiplication} -La multiplication est gérée par la macro \macro{opmul}. - -Nous présenterons les paramètres \texttt{hfactor}, -\texttt{displayintermediary}, \texttt{shiftintermediarysymbol}, -\texttt{displayshiftintermediary} et finalement \texttt{deletezero}, -les autres paramètres ayant été vus à la section~\ref{sec:Parametres - de xlop}. - -Le paramètre \parameter{shiftintermediarysymbol} indique quel symbole -sera utilisé (sa valeur par défaut est \verb+$\cdot$+) pour visualiser -les décalages des nombres intermédiaires. Le paramètre -\parameter{displayshiftintermediary} peut prendre les valeurs -\texttt{shift} (valeur par défaut) qui ne montre ce symbole que -lorsque le décalage est supérieur à un rang, \texttt{all} qui indique -que ce symbole de décalage sera systématiquement affiché et -\texttt{none} qui indique que ce symbole ne sera jamais affiché. -\begin{CenterExample}[xrightmargin=0pt] - \opmul[displayshiftintermediary=shift]{453}{1001205}\qquad - \opmul[displayshiftintermediary=all]{453}{1001205}\qquad - \opmul[displayshiftintermediary=none]{453}{1001205} -\end{CenterExample} - -En réalité, le non affichage des nombres intermédiaires nuls est dû à -la valeur par défaut \texttt{none} du paramètre -\parameter{displayintermediary}. La valeur \texttt{all} va afficher -tous les nombres intermédiaires. -\begin{SideBySideExample} - \opmul[displayintermediary=all] - {453}{1001205} -\end{SideBySideExample} -On notera que les nombres intermédiaires nuls sont affichés avec -autant de chiffres que le premier facteur. - -Le paramètre \parameter{displayintermediary} admet la valeur -\texttt{nonzero} qui a le même rôle que la valeur \texttt{none} sauf -dans le cas où le second facteur ne comporte qu'un seul chiffre. -\begin{CenterExample}[xrightmargin=0pt] - \opmul{3.14159}{4}\qquad - \opmul[displayintermediary=nonzero]{3.14159}{4} -\end{CenterExample} - -Le paramètre \parameter{hfactor} permet d'indiquer comment doit se -faire l'alignement des opérandes. La valeur par défaut \texttt{right} -donne une composition au fer à droite tandis que la valeur -\texttt{decimal} donne un alignement au niveau de la virgule. -\begin{CenterExample}[xrightmargin=0pt] - \opmul{3.1416}{12.8}\qquad\opmul[hfactor=decimal]{3.1416}{12.8} -\end{CenterExample} - -Pour la multiplication posée, le paramètre \parameter{deletezero} ne -concerne que les opérandes, le résultat gardant ses éventuels zéros -non significatifs puisque ceux-ci sont nécessaires pour effectuer -correctement le décalage de la virgule lorsqu'on travaille \og à la -main \fg{}. -\begin{CenterExample}[xrightmargin=0pt] - \opmul[deletezero=false]{01.44}{25}\qquad - \opmul{01.44}{25} -\end{CenterExample} -En revanche, dans la multiplication en ligne, ce paramètre retrouve -son comportement normal. -\begin{CenterExample}[xrightmargin=0pt] - \opmul[deletezero=false,style=text]{01.44}{25}\qquad - \opmul[style=text]{01.44}{25} -\end{CenterExample} - -\section{Division} -\label{sec:Division} -L'extension gère la division \og classique \fg{} avec la macro -\macro{opdiv} et la division euclidienne avec la macro -\macro{opidiv}. En raison de sa complexité, la division est l'opération -qui prend en compte le plus de paramètres. - -\subsection{Contrôle de l'arrêt} -\label{subsec:Controle de l'arret} -Dans ce qui suivra, le terme d'\emph{étape} indique l'ensemble des -calculs permettant d'obtenir un chiffre au niveau du quotient. Ce -nombre d'étapes est contrôlé en partie par les paramètres -\parameter{maxdivstep}, \parameter{safedivstep} et \parameter{period}. -En partie seulement car une division classique s'arrêtera -automatiquement lors de l'obtention d'un reste nul, quelles que que -soient les valeurs de ces trois paramètres et une division euclidienne -s'arrêtera sur un quotient entier, sans tenir compte de ces trois -paramètres. -\begin{SideBySideExample} - \opdiv{25}{7} -\end{SideBySideExample} -\begin{SideBySideExample} - \opidiv{25}{7} -\end{SideBySideExample} -Le premier exemple s'arrête en raison de la valeur de -\parameter{maxdivstep} qui est égale, par défaut, à~10. On prendra -garde à ce que le nombre maximum d'étapes peut entraîner des résultats -aberrants lorsqu'il est trop faible. -\begin{SideBySideExample} - \opdiv[maxdivstep=2]{1248}{3} -\end{SideBySideExample} -Le résultat précédent est clairement faux mais \package{xlop} a fait -ce qu'on lui a demandé, en l'occurrence avoir deux chiffres (maximum) -au quotient. - -L'affichage en ligne va également différer selon que la division s'est -arrêtée avec un reste final nul ou non ou selon qu'il s'agit d'une -division classique ou euclidienne. -\begin{SideBySideExample} - \opdiv[style=text]{3.14}{2}\par - \opdiv[style=text]{3.14}{3}\par - \opidiv[style=text]{314}{2}\par - \opidiv[style=text]{314}{3} -\end{SideBySideExample} -On notera l'emploi de \parameter{equalsymbol} ou -\parameter{approxsymbol} selon le cas ainsi que l'affichage avec une -troncature et non un arrondi. Nous verrons comment obtenir un arrondi -à la section~\ref{sec:Operations evoluees} - -L'affichage en ligne de \verb+\opdiv+ tient compte de -\parameter{maxdivstep}. Cela signifie que l'on peut obtenir des -résultats vraiment faux avec des valeurs trop faible de ce paramètre -et, contrairement à l'affichage posé, l'affichage en ligne ne -permettra pas de comprendre ce qu'il s'est passé. -\begin{SideBySideExample} - \opdiv[maxdivstep=2,style=text] - {1248}{3} -\end{SideBySideExample} -Si en plus, le dernier reste calculé est nul, on atteint un summum : -\begin{SideBySideExample} - \opdiv[maxdivstep=1,style=text] - {1208}{3} -\end{SideBySideExample} -puisqu'il n'y a même plus d'approximation ! - -Une division non euclidienne peut également s'arrêter sur la détection -de la survenue d'une période. Pour cela, il suffit de donner la valeur -\texttt{true} au paramètre \parameter{period}. -\begin{SideBySideExample} - \opdiv[period]{100}{3} -\end{SideBySideExample} - -Pour ne pas avoir à effectuer des comparaisons de chaque reste avec -tous les restes précédents, \package{xlop} calcule dès le départ la -longueur de la période ce qui permet de n'effectuer qu'une seule -comparaison à chaque étape et donc d'accélérer notablement les -calculs\footnote{Je remercie à cette occasion Olivier Viennet pour ses - précisions mathématiques qui ont permis d'implanter correctement ces - calculs.}. Malheureusement, ces calculs se font avec des nombres -directement accessibles à \TeX{} ce qui a pour conséquence de ne pas -pouvoir utiliser d'opérandes dont la valeur absolue excède -$\left\lfloor\frac{2^{31}-1}{10}\right\rfloor = 214748364$. - -Pour ne pas entraîner des calculs trop long, \package{xlop} ne -dépassera pas la valeur du paramètre \parameter{safedivstep} dans les -divisions avec détection de période. Sa valeur par défaut est égale -à~50. Cependant, \package{xlop} signalera le problème. Par exemple si -on demande un tel calcul avec le code : -\begin{Verbatim}[xrightmargin=0pt,frame=none] - \opdiv[period]{1}{289} -\end{Verbatim} -on obtiendra le message d'avertissement : -\begin{Verbatim}[xrightmargin=0pt,frame=none] - xlop warning. Period of division is too big (272 > safedivstep). - Division will stop before reach it. - See documentation for further information. -\end{Verbatim} -qui indique que la période de cette division est de~272 et qu'elle ne -sera donc pas atteinte à cause de la valeur de \texttt{safedivstep}. - -L'affichage en ligne d'une telle division présente quelque -particularités. -\begin{SideBySideExample} - \opdiv[period,style=text]{150}{7} -\end{SideBySideExample} -On obtient donc une égalité au lieu d'une approximation, la présence -d'un trait sous la période et des points de suspension à la suite de -la période. Tous ces éléments peuvent être configurés. Le symbole -d'égalité est donné par le paramètre \parameter{equalsymbol} (valeur -par défaut \verb+{$=$}+), la largeur du trait par le paramètre -\parameter{hrulewidth} (valeur par défaut \texttt{0.4pt}), sa position -verticale par le paramètre \parameter{vruleperiod} (valeur par défaut -\texttt{-0.2}) qui indique un décalage vertical en prenant -\verb+\oplineheight+ comme unité et les points de suspension sont -donnés par le paramètre \parameter{afterperiodsymbol} (valeur par -défaut \verb+$\ldots$+). -\begin{SideBySideExample} - \opdiv[period,style=text, - equalsymbol=$\approx$, - hrulewidth=0.2pt, - vruleperiod=0.7, - afterperiodsymbol=] - {150}{7} -\end{SideBySideExample} - -\subsection{Éléments supplémentaires} -\label{subsec:Elements supplementaires} -Les divisions posées peuvent comporter les soustractions successives -permettant le calcul des restes. Pour \package{xlop}, les nombres qui -sont soustraits sont des nombres intermédiaires donc les différentes -façons de représenter les soustractions utiliserons le paramètre -\parameter{displayintermediary} déjà vu pour la multiplication. La -valeur \texttt{none} (défaut) n'affichera aucune soustraction, la -valeur \texttt{all} affichera toutes les soustractions et la valeur -\texttt{nonzero} affichera les soustractions avec un nombre non nul. -\begin{CenterExample}[xrightmargin=0pt] - \opdiv[displayintermediary=none,voperation=top] - {251}{25}\quad - \opdiv[displayintermediary=nonzero,voperation=top] - {251}{25}\quad - \opdiv[displayintermediary=all,voperation=top] - {251}{25} -\end{CenterExample} - -Lorsqu'on pose une division, on peut dessiner un \og pont \fg{} -au-dessus de la partie du dividende qui sera prise en compte pour la -première étape du calcul. L'extension \package{xlop} permet d'afficher -ce symbole grâce au paramètre booléen \parameter{dividendbridge} -(valeur par défaut \texttt{false}). -\begin{SideBySideExample} - \opdiv[dividendbridge]{1254}{30} -\end{SideBySideExample} - -\subsection{Nombres non entiers et négatifs} -\label{subsec:Nombres non entiers et negatifs} -La présentation d'opérandes non entières est gérée par le paramètre -\parameter{shiftdecimalsep}. Sa valeur par défaut est \texttt{both} et -indique que le séparateur décimal sera décalé pour obtenir un diviseur -et un dividende entiers. La valeur \texttt{divisor} indique qu'il y -aura le décalage nécessaire pour obtenir un diviseur entier et la -valeur \texttt{none} indique qu'il n'y aura aucun décalage. -\begin{CenterExample}[xrightmargin=0pt] - \opdiv[shiftdecimalsep=both]{3.456}{25.6}\quad - \opdiv[shiftdecimalsep=divisor]{3.456}{25.6}\quad - \opdiv[shiftdecimalsep=none]{3.456}{25.6} -\end{CenterExample} - -Un symbole indiqué par le paramètre \parameter{strikedecimalsepsymbol} -est réservé pour montrer l'ancien emplacement de la virgule lorsqu'on -effectue un décalage. La valeur par défaut de ce paramètre est vide ce -qui fait que l'on ne voyait rien sur les exemples précédents. -\begin{CenterExample}[xrightmargin=0pt] - \opset{strikedecimalsepsymbol={\rlap{,}\rule[-1pt]{3pt}{0.4pt}}} - \opdiv[shiftdecimalsep=both]{3.456}{25.6}\quad - \opdiv[shiftdecimalsep=divisor]{3.456}{25.6}\quad - \opdiv[shiftdecimalsep=none]{3.456}{25.6} -\end{CenterExample} - -La présence d'un symbole non vide pour le séparateur décimal barré -peut laisser les zéros non significatifs au niveau des opérandes. -\begin{SideBySideExample} - \opdiv[shiftdecimalsep=divisor, - strikedecimalsepsymbol=% - \hspace{-3pt}\tiny$\times$] - {0.03456}{2.56} -\end{SideBySideExample} - -Comme nous l'avons déjà vu, la macro \macro{opidiv} donne un quotient -entier, cela même si les opérandes sont non entières. Il est un peu -bizarre de vouloir réaliser une division euclidienne sur des nombres -non entiers et la macro \macro{opidiv} sera assez stricte sur sa -présentation. Les paramètres \parameter{maxdivstep}, -\parameter{safedivstep} et \parameter{period} seront sans effet ainsi -que le paramètre \parameter{shiftdecimalsep}, les deux opérandes étant -rendues entières. -\begin{SideBySideExample} - \opidiv[strikedecimalsepsymbol=% - \hspace{-3pt}\tiny$\times$] - {34.57}{7} -\end{SideBySideExample} - -Lorsque les opérandes sont négatives, l'affichage en ligne de -\macro{opidiv} différera des données obtenues avec l'affichage -posée. Le reste sera nécessairement un nombre compris entre zéro -(inclus) et la valeur absolue du diviseur (exclu). -\begin{SideBySideExample} - \opdiv[style=text]{124}{7}\par - \opidiv[style=text]{124}{7}\par - \opidiv[style=text]{124}{-7}\par - \opidiv[style=text]{-124}{7}\par - \opidiv[style=text]{-124}{-7} -\end{SideBySideExample} - -Cette condition sur le reste reste valable même avec un diviseur non -entier. -\begin{SideBySideExample} - \opidiv[style=text]{1.24}{0.7}\par - \opidiv[style=text]{1.24}{-0.7}\par - \opidiv[style=text]{-1.24}{0.7}\par - \opidiv[style=text]{-1.24}{-0.7} -\end{SideBySideExample} - -\chapter{Autres commandes} -\label{chap:Autres commandes} -\section{Macros étoilées} -\label{sec:Macros etoilees} -Les cinq macros vues au chapitre précédent ont une version -étoilée. Ces macros étoilées réalisent le calcul mais ne procèdent à -aucun affichage, le résultat étant stocké dans une variable donnée en -dernier argument. - -Comme ces commandes n'affichent rien, les paramètres ne seront pas -acceptés pour les macros \macro{opadd*}, \macro{opsub*}, -\macro{opmul*} et \macro{opidiv*}. En revanche, les paramètres -\parameter{maxdivestep}, \parameter{safedivstep} et \parameter{period} -influencent les calculs et la macro \macro{opdiv*} acceptera donc un -argument optionnel pour pouvoir en tenir compte. -\begin{SideBySideExample} - \opmul*{2}{2}{a}% - \opmul*{a}{a}{a}\opmul*{a}{a}{a}% - \opadd[style=text]{a}{1} -\end{SideBySideExample} -Pour les macros \macro{opdiv} et \macro{opidiv}, il y aura deux -arguments supplémentaires pour pouvoir recevoir le quotient et le -reste final. -\begin{SideBySideExample} - \opdiv*[maxdivstep=1]{-88}{16}{q}{r}% - \opmul*{q}{16}{bq}% - \opmul[style=text]{16}{q}\par - \opadd[style=text]{bq}{r} -\end{SideBySideExample} - -\section{Entrées-sorties} -\label{sec:Entree-sorties} -La macro \macro{opcopy} recopie son premier argument dans son deuxième -argument. Le premier argument est donc un nombre écrit sous forme -décimale ou via une variable alors que le second sera considérée comme -un nom de variable. - -La macro \macro{opprint} affiche son argument. L'exemple qui suit -utilise le compteur \macro{time} qui indique le nombre de minutes -écoulés depuis minuit. -\begin{SideBySideExample} - \opidiv*{\the\time}{60}{h}{m}% - Il est \opprint{h}~heures et - \opprint{m}~minutes -\end{SideBySideExample} -On verra à la section~\ref{sec:Comparaisons} comment améliorer cet -affichage avec des tests. - -La macro \macro{opdisplay} affiche également un nombre mais en -écrivant chaque chiffre dans une boîte de largeur donnée par -\parameter{columnwidth} et de hauteur donnée par -\parameter{lineheight}. Le style est spécifié par le premier argument -et cette macro accepte un argument optionnel pour permettre de donner -un style particulier aux chiffres individuels. -\begin{SideBySideExample} - \opdisplay[resultstyle.1=\bfseries, - resultstyle.-2=\bfseries] - {resultstyle}{129.192} -\end{SideBySideExample} - -Les macros \macro{oplput} et \macro{oprput} permettent de placer un -objet à un emplacement déterminé. La syntaxe de ces deux commandes ne -suit pas celle des autres macros de \package{xlop} puisque -l'emplacement est indiqué sous forme de coordonnées entre -parenthèses. Les coordonnées utilisent \macro{opcolumnwidth} et -\macro{oplineheight} comme unités ce qui permet à l'utilisateur de -construire lui-même ses propres \og opérations \fg. -\begin{SideBySideExample} - \psset{xunit=\opcolumnwidth, - yunit=\oplineheight}% - \psgrid[subgriddiv=1,gridlabels=7pt, - griddots=5](0,1)(10,-2) - \oplput(2,0){Bonjour} - \oprput(8,-1){le monde} - $\bullet$ -\end{SideBySideExample} -Sur l'exemple ci-dessus, on peut voir que ces deux macros ne modifient -pas le point de référence. Elles prennent même la précaution d'inhiber -l'espace automatique qui les suit pour qu'il ne soit pas nécessaire de -mettre un \verb+%+ en fin de ligne. - -Les macros \macro{ophline} et \macro{opvline} complète les deux -précédentes pour donner à l'utilisateur les outils lui permettant de -construire ses propres opérations. La macro \macro{ophline} permet de -placer un trait horizontal dont la longueur est donné par le paramètre -qui suit les coordonnées. La macro \macro{opvline} fait de même avec -les traits verticaux. On rappelle que les paramètres -\parameter{hrulewidth} et \parameter{vrulewidth} indiquent les -épaisseurs respectives de ces types de traits. -\begin{CenterExample}[xrightmargin=0pt] - \par\vspace{2\oplineheight} - \oplput(1,2){O}\oplput(2,2){N}\oplput(3,2){E} - \oplput(0,1.5){$+$} - \oplput(1,1){O}\oplput(2,1){N}\oplput(3,1){E} - \ophline(0,0.8){4} - \oplput(1,0){T}\oplput(2,0){W}\oplput(3,0){O} -\end{CenterExample} - -\section{Chiffres d'un nombre} -\label{sec:Chiffres d'un nombre} -Les macros \macro{opwidth}, \macro{opintegerwidth} et -\macro{opdecimalwidth} indiquent respectivement le nombre de chiffres -du nombre dans sa totalité, de sa partie entière et de sa partie -décimale. Le premier argument est le nombre sur lequel s'effectue le -comptage et le second argument indique la variable où sera stocké le -résultat. -\begin{SideBySideExample} - \opcopy{123456.1234}{a}% - \opwidth{a}{na}% - \opintegerwidth{a}{ia}% - \opdecimalwidth{a}{da}% - \opprint{a} s'\'ecrit avec \opprint{na} - chiffres (\opprint{ia} en partie - enti\`ere et \opprint{da} en partie - d\'ecimale). -\end{SideBySideExample} - -La macro \macro{opunzero} permet de supprimer les zéros non -significatifs\index{zeros non significatifs@zéros non significatifs} -du nombre passé en argument. -\begin{SideBySideExample} - \opcopy{00150.00250}{a}% - Avant : \opprint{a}\par - \opunzero{a}% - Apr\`es : \opprint{a} -\end{SideBySideExample} - -Les macros \macro{integer} et \macro{opdecimal} donnent respectivement -la partie entière et la partie décimale d'un nombre. Le premier -argument est le nombre à traiter et le second est la variable qui -contiendra le résultat. -\begin{SideBySideExample} - \opcopy{-37.69911}{a}% - \opinteger{a}{ia}% - \opdecimal{a}{da}% - Partie enti\`ere : \opprint{ia}\par - Partie d\'ecimale : \opprint{da} -\end{SideBySideExample} - -Six macros servent à écrire ou lire un chiffre d'un nombre. On peut -lire ou écrire un chiffre selon son rang dans le nombre, dans sa -partie entière ou dans sa partie décimale. Les chiffres pour le nombre -dans sa totalité ou pour sa partie entière sont numérotés de droite à -gauche et, pour sa partie décimale de gauche à droite. Ainsi, avec le -nombre 1234,56789, le deuxième chiffre est 8, le deuxième chiffre de -sa partie entière est 3 et le deuxième chiffre de sa partie décimale -est 6. Il est alors facile de deviner le rôle respectif des six macros -: -\begin{itemize} -\item \parameter{opgetdigit} ; -\item \parameter{opsetdigit} ; -\item \parameter{opgetintegerdigit} ; -\item \parameter{opsetintegerdigit} ; -\item \parameter{opgetdecimaldigit} ; -\item \parameter{opsetdecimaldigit} ; -\end{itemize} -La syntaxe est la même pour ces six macros. Le premier argument est le -nombre sur lequel doit porter la lecture ou l'écriture, le deuxième -argument est l'index donnant la position du chiffre et le troisième -argument est le nom de la variable qui contiendra le chiffre lu ou -bien ce qui devra être écrit. Si l'index est en dehors du nombre, les -macros de lecture donneront \texttt{0} comme résultat et les macros -d'écriture étendront le nombre pour pouvoir atteindre cet index en -créant des zéros dans les nouvelles positions. - -\section{Comparaisons} -\label{sec:Comparaisons} -Lorsqu'on désire concevoir des macros évoluées, il est très souvent -utile de pouvoir réaliser des tests. Pour cela, \package{xlop} met à -disposition la macro \macro{opcmp} dont les deux arguments sont des -nombres et qui mettra à jour les tests \macro{ifopgt}, \macro{ifopge}, -\macro{ifople}, \macro{ifoplt}, \macro{ifopeq} et \macro{ifopneq} pour -respectivement indiquer que la première opérande est strictement -supérieure, supérieure, inférieure, strictement inférieure, égale ou -différente de la seconde opérande. - -Pour des raisons techniques, \package{xlop} donne des définitions -globales aux six tests précédents. Ceux-ci ne seront donc pas protégés -par les groupes. Comme ces tests sont utilisés par un grand nombre de -macros de \package{xlop}, une conséquence pratique est qu'il faut -\textbf{toujours} réaliser les tests \verb+\ifop...+ immédiatement -après le \macro{opcmp}, ou, du moins, avant toute autre utilisation de -macros de \package{xlop} sous peine de bogues éventuels difficiles à -comprendre ! - -On va reprendre la macro d'affichage de l'heure donnée à la -section~\ref{sec:Entree-sorties} mais en vérifiant si l'argument est -compris entre~0 (inclus) et~1440 (exclu) puis en réalisant les tests -nécessaires pour voir si \og heure \fg{} doit être ou non au pluriel -ainsi que \og minute \fg{}. - -\begin{CenterExample}[xrightmargin=0pt] - \newcommand\heure[1]{% - \opcmp{#1}{0}\ifopge - \opcmp{#1}{1440}\ifoplt - \opidiv*{#1}{60}{h}{m}% - \opprint{h} heure% - \opcmp{h}{1}\ifopgt - s% - \fi - \opcmp{m}{0}\ifopneq - \space\opprint{m} minute% - \opcmp{m}{1}\ifopgt - s% - \fi - \fi - \fi\fi - } - \heure{60} -- \heure{1080} -- \heure{1081} -- \heure{1082} -\end{CenterExample} - -\section{Opérations évoluées} -\label{sec:Operations evoluees} -Les macros qui nous restent à voir proviennent soit de commandes -utilisées de façon interne et qu'il aurait été dommage de ne pas -rendre publiques, soit de demandes d'utilisateurs. - -Les macros utilisées de façon interne sont \macro{opgcd} qui donne le -pgcd de deux nombres et \macro{opdivperiod} qui donne la longueur de -la période d'un quotient de deux nombres. Pour des raisons -d'efficacité, ces macros n'utilisent pas les nombres de \package{xlop} -mais des nombres directement accessibles à \TeX{}. Cela a pour -conséquence que les nombres passés en paramètres dans les deux -premiers arguments ne devront pas excéder \texttt{2147483647} pour -\macro{opgcd} et \texttt{214748364} pour \macro{opdivperiod}. Un -message d'avertissement rappellera à l'ordre en cas de dépassement. Le -résultat sera stocké dans la variable indiqué en troisième paramètre. - -Il y aura également quelques vérifications sur les deux premiers -paramètres. Un pgcd ne peut pas avoir d'argument nul et le calcul de -la longueur d'une période ne pourra pas se faire avec un quotient -nul. D'autre part, si un nombre non entier est passé en paramètre, -seule la partie entière sera prise en compte. -\begin{SideBySideExample} - \opcopy{5376}{a}% - \opcopy{2304}{b}% - \opgcd{a}{b}{gcd(ab)}% - \newcommand\pgcd{% - \mathop{\mathrm{pgcd}}}% - $\pgcd(\opprint{a},\opprint{b}) = - \opprint{gcd(ab)}$ -\end{SideBySideExample} -Si vous voulez vous amuser à trouver de grandes périodes de divisions, -sans entrer dans les détails mathématiques, les carrés de nombres -premiers sont de bons candidats. Par exemple, avec $257^2=66049$ on -trouve : -\begin{SideBySideExample} - \opdivperiod{1}{66049}{p}% - $\frac{1}{66049}$ a une p\'eriode - de longueur $\opprint{p}$. -\end{SideBySideExample} - -Les macros \macro{opcastingoutnines} et \macro{opcastingoutelevens} -vont permettre de composer des preuves par neuf et par onze. -L'extension \package{xlop} ne propose pas directement ces compositions -puisqu'elles nécessitent des traits en diagonal et donc le recours à -d'autres extensions. En réalité, la macro \macro{opcastingoutnines} va -faire la somme modulo~9 des chiffres du premier argument et stockera -le résultat dans le second argument tandis que la macro -\macro{opcastingoutelevens} fera la somme des chiffres de rangs -impairs, la somme des chiffres de rangs pairs puis la différence -modulo~11 de ces deux sommes. -\begin{SideBySideExample} - \newcommand\castingoutnines[3]{% - \opcastingoutnines{#1}{cna}% - \opcastingoutnines{#2}{cnb}% - \opmul*{cna}{cnb}{cna*cnb} - \opcastingoutnines{cna*cnb}{cna*cnb}% - \opcastingoutnines{#3}{cn(a*b)}% - \begin{pspicture}(-3.5ex,-3.5ex)% - (3.5ex,3.5ex) - \psline(-3.5ex,-3.5ex)(3.5ex,3.5ex) - \psline(-3.5ex,3.5ex)(3.5ex,-3.5ex) - \rput(-2.75ex,0){\opprint{cna}} - \rput(2.75ex,0){\opprint{cnb}} - \rput(0,2.75ex){\opprint{cna*cnb}} - \rput(0,-2.75ex){\opprint{cn(a*b)}} - \end{pspicture} - } - \castingoutnines{157}{317}{49669} -\end{SideBySideExample} -Incidemment, cet exemple montre que $157\times317\neq49669$ ! La -réponse correcte est \opmul[style=text]{157}{317}. - -Les deux macros suivantes sont très simples. Il s'agit de -\macro{opneg} qui calcul l'opposé de son premier argument et le -sauvegarde dans la variable indiquée par le second argument et de -\macro{opabs} qui réalise la même chose mais avec la valeur absolue. - -La macro \macro{oppower} permet de calculer des puissances entières de -nombres. Cette macro demande trois paramètres, le troisième paramètre -étant la variable recevant le résultat du premier paramètre à la -puissance le deuxième paramètre. Le deuxième paramètre doit être un -nombre entier. Lorsque le premier argument est nul, si le deuxième -paramètre est nul, le résultat sera~1, s'il est strictement positif, -le résultat sera nul et s'il est strictement négatif il y aura une -erreur et aucun résultat ne sera fourni. Il n'y a aucune limitation -sur le premier paramètre ce qui peut entraîner quelques problèmes. Par -exemple : -\begin{CenterExample}[xrightmargin=0pt] - \opcopy{0.8}{a}\opcopy{-17}{n}% - \oppower{a}{n}{r}% - $\opprint{a}^{\opprint{n}} = \opprint{r}$ -\end{CenterExample} -Avec $0{,}7$ au lieu de $0{,}8$, le problème aurait été encore pire : -\begin{CenterExample}[xrightmargin=0pt] - \opcopy{0.7}{a}\opcopy{-8}{n}% - \oppower{a}{n}{r}% - \opdecimalwidth{r}{dr} - $\opprint{a}^{\opprint{n}}$ a \opprint{dr} chiffres apr\`es la - virgule. -\end{CenterExample} -Tout cela est dû au fait que lorsque l'exposant est négatif, -\package{xlop} calcule \emph{d'abord} l'inverse du nombre pour -\emph{ensuite} calculer la puissance avec l'opposé de l'exposant. Si -on avait laissé $-17$ au lieu de $-8$ dans l'exemple précédent, les -capacités de \TeX{} auraient été dépassées. - -Les trois macros qui suivent permettent de contrôler la précision des -nombres manipulés. Elles permettent de construire un nombre en donnant -une valeur approchée par défaut, par excès ou un arrondi d'un nombre -donné en précisant le rang où devra se faire l'arrondi. Ces macros -sont respectivement \macro{opfloor}, \macro{opceil} et -\macro{opround}. Elles demandent trois paramètres qui seront dans -l'ordre le nombre de départ, le rang de l'arrondi et le nom de la -variable qui contiendra le résultat. - -Le rang est indiqué par une valeur entière donnant le nombre de -chiffres après la virgule qui doivent être présents. Si le rang est -négatif, l'arrondi se fera avant la virgule. Si le rang positif -indique plus de chiffres que la partie décimale n'en a, des zéros -seront ajoutés. Si le rang négatif indique plus de chiffres que la -partie entière n'en a, l'arrondi restera bloqué pour donner au moins -le premier chiffre du nombre. - -Voici un tableau récapitulatif pour mieux comprendre le fonctionnement -de ces trois macros. -\begin{center} - \opcopy{3838.3838}{a} - \begin{tabular}{|r|l|l|l|} - \hline - \multicolumn{4}{|c|}{\textbf{\texttt{\textbackslash - op\ldots{}\{3838.3838\}\{n\}\{r\}}}}\\\hline - \multicolumn{1}{|c|}{\textbf{\texttt{n}}} & - \multicolumn{1}{c|}{\textbf{\texttt{floor}}} & - \multicolumn{1}{c|}{\textbf{\texttt{ceil}}} & - \multicolumn{1}{c|}{\textbf{\texttt{round}}} \\\hline - \opcopy{6}{n}$\opprint{n}$ & - \opfloor{a}{n}{r}$\opprint{r}$ & - \opceil{a}{n}{r}$\opprint{r}$ & - \opround{a}{n}{r}$\opprint{r}$ \\ - \opcopy{4}{n}$\opprint{n}$ & - \opfloor{a}{n}{r}$\opprint{r}$ & - \opceil{a}{n}{r}$\opprint{r}$ & - \opround{a}{n}{r}$\opprint{r}$ \\ - \opcopy{3}{n}$\opprint{n}$ & - \opfloor{a}{n}{r}$\opprint{r}$ & - \opceil{a}{n}{r}$\opprint{r}$ & - \opround{a}{n}{r}$\opprint{r}$ \\ - \opcopy{0}{n}$\opprint{n}$ & - \opfloor{a}{n}{r}$\opprint{r}$ & - \opceil{a}{n}{r}$\opprint{r}$ & - \opround{a}{n}{r}$\opprint{r}$ \\ - \opcopy{-1}{n}$\opprint{n}$ & - \opfloor{a}{n}{r}$\opprint{r}$ & - \opceil{a}{n}{r}$\opprint{r}$ & - \opround{a}{n}{r}$\opprint{r}$ \\ - \opcopy{-2}{n}$\opprint{n}$ & - \opfloor{a}{n}{r}$\opprint{r}$ & - \opceil{a}{n}{r}$\opprint{r}$ & - \opround{a}{n}{r}$\opprint{r}$ \\ - \opcopy{-6}{n}$\opprint{n}$ & - \opfloor{a}{n}{r}$\opprint{r}$ & - \opceil{a}{n}{r}$\opprint{r}$ & - \opround{a}{n}{r}$\opprint{r}$ \\\hline - \end{tabular} - \opcopy{-3838.3838}{a} - \begin{tabular}{|r|l|l|l|} - \hline - \multicolumn{4}{|c|}{\textbf{\texttt{\textbackslash - op\ldots{}\{-3838.3838\}\{n\}\{r\}}}}\\\hline - \multicolumn{1}{|c|}{\textbf{\texttt{n}}} & - \multicolumn{1}{c|}{\textbf{\texttt{floor}}} & - \multicolumn{1}{c|}{\textbf{\texttt{ceil}}} & - \multicolumn{1}{c|}{\textbf{\texttt{round}}} \\\hline - \opcopy{6}{n}$\opprint{n}$ & - \opfloor{a}{n}{r}$\opprint{r}$ & - \opceil{a}{n}{r}$\opprint{r}$ & - \opround{a}{n}{r}$\opprint{r}$ \\ - \opcopy{4}{n}$\opprint{n}$ & - \opfloor{a}{n}{r}$\opprint{r}$ & - \opceil{a}{n}{r}$\opprint{r}$ & - \opround{a}{n}{r}$\opprint{r}$ \\ - \opcopy{3}{n}$\opprint{n}$ & - \opfloor{a}{n}{r}$\opprint{r}$ & - \opceil{a}{n}{r}$\opprint{r}$ & - \opround{a}{n}{r}$\opprint{r}$ \\ - \opcopy{0}{n}$\opprint{n}$ & - \opfloor{a}{n}{r}$\opprint{r}$ & - \opceil{a}{n}{r}$\opprint{r}$ & - \opround{a}{n}{r}$\opprint{r}$ \\ - \opcopy{-1}{n}$\opprint{n}$ & - \opfloor{a}{n}{r}$\opprint{r}$ & - \opceil{a}{n}{r}$\opprint{r}$ & - \opround{a}{n}{r}$\opprint{r}$ \\ - \opcopy{-2}{n}$\opprint{n}$ & - \opfloor{a}{n}{r}$\opprint{r}$ & - \opceil{a}{n}{r}$\opprint{r}$ & - \opround{a}{n}{r}$\opprint{r}$ \\ - \opcopy{-6}{n}$\opprint{n}$ & - \opfloor{a}{n}{r}$\opprint{r}$ & - \opceil{a}{n}{r}$\opprint{r}$ & - \opround{a}{n}{r}$\opprint{r}$ \\\hline - \end{tabular} -\end{center} - -La dernière macro qui nous reste à voir est \macro{opexpr} qui permet -de réaliser le calcul d'une expression complexe. Cette macro demande -deux paramètres : le premier est l'expression à calculer donnée sous -forme infixe (la forme habituelle pour un humain) et le second est le -nom de la variable qui contiendra le résultat. - -Initialement, la formule devait être donnée sous forme polonaise -inverse (la notation des calculatrices HP ou du langage PostScript par -exemple) mais un travail commun avec Christophe Jorssen a finalement -abouti à la possibilité de donner l'expression sous une forme plus -agréable pour l'utilisateur. - -Les formules acceptent les opérateurs arithmétiques habituels -\texttt{+}, \texttt{-}, \texttt{*} et \texttt{/} ainsi que l'opérateur -\texttt{:} pour la division euclidienne et \verb+^+ pour -l'exponentiation. L'opérateur \texttt{-} a les deux rôles d'opérateur -binaire de la soustraction et d'opérateur unaire pour l'opposé. -L'opérateur \texttt{+} a également les deux rôles d'opérateur binaire -de l'addition et d'opérateur unaire ne faisant \ldots{} rien ! Les -opérandes sont écrites sous forme décimale ou par l'intermédiaire de -nom de variable cependant, la macro \macro{opexpr} va introduire une -petite restriction sur les noms de variables puisque ceux-ci devront -être différents des noms de fonctions reconnus par cette macro. Les -fonctions accessibles sont : -\begin{itemize} -\item \texttt{abs(a)} ; -\item \texttt{ceil(a,i)} ; -\item \texttt{decimal(a)} ; -\item \texttt{floor(a,i)} ; -\item \texttt{gcd(a,b)} ; -\item \texttt{integer(a)} ; -\item \texttt{mod(a,b)} qui donne le résultat de \texttt{a} modulo - \texttt{b} ; -\item \texttt{rest(a,b)} qui donne le reste de la division de - \texttt{a} par \texttt{b} (la différence entre reste et modulo est - la différence qui existe entre division non euclidienne et division - euclidienne) ; -\item \texttt{round(a,i)}. -\end{itemize} -où les fonctions non décrites ci-dessus font appel aux macros -correspondantes (la fonction \texttt{xxx} faisant appel à la macro -\verb+\opxxx+). Pour les fonctions \texttt{ceil}, \texttt{floor} et -\texttt{round}, le nombre \texttt{i} indique le rang sur lequel doit -se faire l'arrondi. - -La macro \macro{opexpr} accepte un argument optionnel puisqu'elle peut -réaliser des divisions et que ces divisions doivent pouvoir être -contrôlées via les paramètres \parameter{maxdivstep}, -\parameter{safedivstep} et \parameter{period}. -Notre premier exemple est assez basique : -\begin{CenterExample}[xrightmargin=0pt] - \opexpr{3--gcd(15*17,25*27)*2}{r}% - $3--\gcd(15\times17,25\times27)\times2 = \opprint{r}$ -\end{CenterExample} - -Voici un autre exemple montrant que des données peuvent provenir d'une -macro : -\begin{CenterExample}[xrightmargin=0pt] - \newcommand\try{2}% - \opexpr{\try+1/ - (\try+1/ - (\try+1/ - (\try+1/ - (\try+1/ - (\try)))))}{r} - La fraction continue de base $u_n=2$ vaut \opprint{r} au rang~5. -\end{CenterExample} - -\appendix -\chapter{Aide-mémoire} -\label{chap:Aide-mémoire} -\section{Temps de compilation} -\label{sec:Temps de compilation} -Les temps de compilation ont été mesurés sur une machine à processeur -Pentium~II~600\,MHz ayant 256\,Mo de RAM et tournant sous linux -(Debian woody). Le principe a été de faire un fichier TeX{} minimum -dont le schéma général est donné par : -\begin{verbatim} - \input xlop - \count255=0 - \loop - \ifnum\count255<1000 - - \advance\count255 by1 - \repeat - \bye -\end{verbatim} -Le temps de compilation avec \verb++ vide a été -soustrait des autres tests et seul le temps utilisateur a été pris en -compte. Les résultats sont donnés en millisecondes et sont évidemment -à prendre avec beaucoup de précautions. - -\index{compilation (temps de)|(}\index{temps de calcul|(}% -Le tableau suivant donne le temps de compilation des opérations en -millisecondes. Les opérandes utilisées l'ont été avec une écriture -sous forme de chiffres mais des essais avec des opérandes sous forme -de noms de variable ont montré que les différences étaient vraiment -minimes. - -La première ligne indique le nombre de chiffres des deux -opérandes. Ces nombres ont été construits de la façons suivantes : -\begin{itemize} -\item $\mathrm{A} = 1$ et $\mathrm{B} = 9$ pour un chiffre ; -\item $\mathrm{A} = 12$ et $\mathrm{B} = 98$ pour deux chiffres ; -\item $\mathrm{A} = 123$ et $\mathrm{B} = 987$ pour trois chiffres ; -\item $\mathrm{A} = 12345$ et $\mathrm{B} = 98765$ pour cinq chiffres ; -\item $\mathrm{A} = 1234567890$ et $\mathrm{B} = 9876543210$ pour dix - chiffres ; -\item $\mathrm{A} = 12345678901234567890$ et $\mathrm{B} = - 98765432109876543210$ pour vingt chiffres ; -\end{itemize} -Voici les résultats, quelques commentaires suivront : - -\bigskip\noindent\hbox to\linewidth{\hss - \begin{tabular}{|r|*{6}{l|}} - \cline{2-7} - \multicolumn{1}{l|}{} & - \multicolumn{1}{c|}{1} & - \multicolumn{1}{c|}{2} & - \multicolumn{1}{c|}{3} & - \multicolumn{1}{c|}{5} & - \multicolumn{1}{c|}{10} & - \multicolumn{1}{c|}{20} \\\hline - \verb+\opadd*{A}{B}{r}+ & - 1.1 & 1.4 & 1.6 & 2.1 & 3.3 & 5.8 \\\cline{2-7} - \verb+\opadd*{B}{A}{r}+ & - 1.1 & 1.4 & 1.6 & 2.1 & 3.3 & 5.8 \\\hline - \verb+\opsub*{A}{B}{r}+ & - 1.7 & 2.1 & 2.4 & 3.0 & 4.8 & 8.3 \\\cline{2-7} - \verb+\opsub*{B}{A}{r}+ & - 1.5 & 1.7 & 2.0 & 2.6 & 4.0 & 7.0 \\\hline - \verb+\opmul*{A}{B}{r}+ & - 4.6 & 6.3 & 8.2 & 12.8 & 29.9 & 87.0 \\\cline{2-7} - \verb+\opmul*{B}{A}{r}+ & - 5.0 & 6.6 & 8.5 & 13.2 & 30.3 & 87.8 \\\hline - \verb+\opdiv*{A}{B}{q}{r}+ & - 46.4 & 53.8 & 53.8 & 64.3 & 85.8 & 124.7 \\\cline{2-7} - \verb+\opdiv*{B}{A}{q}{r}+ & - 12.4 & 48.9 & 55.7 & 58.6 & 72.8 & 111.0 \\\hline - \verb+\opdiv*[maxdivstep=5]{A}{B}{q}{r}+ & - 26.8 & 30.0 & 32.6 & 37.6 & 49.5 & 73.5 \\\cline{2-7} - \verb+\opdiv*[maxdivstep=5]{B}{A}{q}{r}+ & - 12.4 & 29.1 & 32.6 & 35.2 & 43.3 & 67.9 \\\hline - \verb+\opidiv*{A}{B}{q}{r}+ & - 10.8 & 12.2 & 13.5 & 16.0 & 22.3 & 35.5 \\\cline{2-7} - \verb+\opidiv*{B}{A}{q}{r}+ & - 11.6 & 13.0 & 14.2 & 16.6 & 23.0 & 36.7 \\\hline - \verb+\opidiv*{A}{2}{q}{r}+ & - 10.7 & 12.0 & 15.3 & 22.3 & 42.9 & 83.0 \\\hline - \end{tabular} - \hss -} -\par\bigskip -Il est normal que l'inversion des opérandes n'ait aucune influence -pour l'addition. Il peut alors sembler anormal qu'elle en ait une pour -la soustraction mais en fait, avoir une seconde opérande supérieure à -la première va entraîner quelques instructions supplémentaires (double -inversion, gestion plus longue du signe du résultat). - -Il est normal que le temps de la division soit supérieur à celui de la -multiplication. Il peut alors sembler anormal que la division ait -l'air de \og rattraper \fg{} son retard. En fait, une multiplication -voit sa complexité fortement augmenter avec la taille des opérandes -mais la division normale est bloquée par le paramètre -\parameter{maxdivstep}. On le voit bien sur l'exemple où on limite ce -maximum à 5~étapes. - -Quelques résultats semblent bizarres. Ainsi, -\verb+\opdiv*{9}{1}{q}{r}+ est anormalement rapide : cela est dû -au fait d'avoir un quotient à un seul chiffre. Plus bizarre encore, -\verb+\opdiv*{123}{987}{q}{r}+ est plutôt rapide. Ici, -l'explication est plus subtile : cela est dû à la présence de nombreux -zéros au quotient. - -Avec des opérandes de taille comparable, la division euclidienne est -très rapide par rapport à la division non euclidienne. Cela est dû au -fait que le quotient n'aura que peu de chiffres (un seul avec tous les -nombres \texttt{A} et \texttt{B}). La dernière ligne du tableau est -plus représentative des temps de compilation que l'on peut obtenir -avec cette opération. - -Toutes ces remarques sont faites pour bien insister sur la difficulté -à évaluer un temps de compilation a priori : il dépend de trop de -paramètres. Cela dit, le tableau permet d'avoir quand même une idée de -ce à quoi il faut s'attendre. -\index{compilation (temps de)|)}\index{temps de calcul|)} - -\section{Liste des macros} -\label{sec:Liste des macros} -\noindent\index{macros!table des|(}% -\begin{longtable}{|l|p{6.3cm}|} - \hline - \multicolumn{1}{|c|}{\textbf{Macro}} & - \multicolumn{1}{c|}{\textbf{Description}} \\\hline\hline - \endfirsthead - \hline - \multicolumn{1}{|c|}{\textbf{Macro}} & - \multicolumn{1}{c|}{\textbf{Description}} \\\hline\hline - \endhead - \hline - \multicolumn{2}{|c|}{$\ldots$ à suivre $\ldots$}\\ - \hline - \endfoot - \hline - \endlastfoot - \verb+\opabs{n}{N}+ & - \verb+N+ reçoit la valeur absolue de \verb+n+. \\\hline - \verb+\opadd[P]{n1}{n2}+ & - Affiche le résultat de l'opération \verb-n1+n2-. \\\hline - \verb+\opadd*{n1}{n2}{N}+ & - Calcule \verb-n1+n2- et place le résultat dans - \verb+N+. \\\hline - \verb+\opcastingoutelevens{n}{N}+ & - Calcule la différence (modulo 11) de la somme des chiffres de rang - impair et de la somme des chiffres de rang pair de \verb+n+ et - place le résultat dans \verb+N+. \\\hline - \verb+\opcastingoutnines{n}{N}+. & - Calcule la somme modulo 9 des chiffres de \verb+n+ et place le - résultat dans \verb+N+. \\\hline - \verb+\opceil{n}{T}{N}+ & - Place dans \verb+N+ la valeur approchée par excès de - \verb+n+ au rang \verb+T+. \\\hline - \verb+\opcmp{n1}{n2}+ & - Compare les nombres \verb+n1+ et \verb+n2+ et réalise la - mise à jour correspondante des tests \verb+\ifopeq+, - \verb+\ifopneq+, \verb+\ifopgt+, \verb+\ifopge+, - \verb+\ifople+ et \verb+\ifoplt+. \\\hline - \verb+\opcopy{n}{N}+ & - Copie le nombre \verb+n+ dans \verb+N+. \\\hline - \verb+\opdecimal{n}{N}+ & - Copie la partie décimale (nombre entier positif) de \verb+n+ - dans \verb+N+. \\\hline - \verb+\opdecimalwidth{n}{N}+ & - Le nombre \verb+N+ reçoit la largeur de la partie décimale du - nombre \verb+n+. \\\hline - \verb+\opdisplay[P]{S}{n}+ & - Affiche le nombre \verb+n+ avec le style \verb+S+ en - plaçant chaque chiffre dans une boîte de largeur - \verb+\opcolumnwidth+ et de hauteur - \verb+\oplineheight+. \\\hline - \verb+\opdiv[P]{n1}{n2}+ & - Affiche le résultat de l'opération n1/n2. \\\hline - \verb+\opdiv*[P]{n1}{n2}{N1}{N2}+ & - Calcule \verb+n1/n2+, place le quotient dans \verb+N1+ et - le reste dans \verb+N2+. \\\hline - \verb+\opdivperiod{T1}{T2}{N}+ & - Calcule la longueur de la période de la division de \verb+T1+ - par \verb+T2+ et place le résultat dans \verb+N+. \\\hline - \verb+\opexpr[P]{F}{N}+ & - \'Évalue la formule \texttt{F} est place le résultat final dans le - nombre \texttt{N}. \\\hline - \verb+\opfloor{n}{T}{N}+ & - Place dans \verb+N+ la valeur approchée par défaut de - \verb+n+ au rang \verb+T+. \\\hline - \verb+\opgcd{T1}{T2}{N}+ & - Calcule le pgcd de \verb+T1+ et \verb+T2+ et place le - résultat dans \verb+N+. \\\hline - \verb+\opgetdecimaldigit{n}{T}{N}+ & - Construit le nombre \verb+N+ avec le seul chiffre situé en - \verb+T+ième position de la partie décimale du nombre - \verb+n+. \\\hline - \verb+\opgetdigit{n}{T}{N}+ & - Construit le nombre \verb+N+ avec le seul chiffre situé en - \verb+T+ième position du nombre \verb+n+. \\\hline - \verb+\opgetintegerdigit{n}{T}{N}+ & - Construit le nombre \verb+N+ avec le seul chiffre situé en - \verb+T+ième position de la partie entière du nombre - \verb+n+. \\\hline - \verb+\ophline(T1,T2){T3}+ & - Trace un trait horizontal de longueur \verb+T3+, d'épaisseur - \verb+hrulewidth+ et débutant en \verb+(T1,T2)+ par - rapport au point de référence. \\\hline - \verb+\opidiv[P]{n1}{n2}+ & - Affiche le résultat de l'opération \verb+n1/n2+ (division - euclidienne, c'est-à-dire avec un quotient entier). \\\hline - \verb+\opidiv*{n1}{n2}{N1}{N2}+ & - Calcule \verb+n1/n2+ (division euclidienne), place le quotient - (entier) dans \verb+N1+ et le reste (compris entre 0 inclus et - \verb+|n2|+ exclu) dans \verb+N2+. \\\hline - \verb+\opinteger{n}{N}+ & - Copie la partie entière (nombre entier positif) de \verb+n+ - dans \verb+N+. \\\hline - \verb+\opintegerwidth{n}{N}+ & - Le nombre \verb+N+ reçoit la longueur de la partie entière du - nombre \verb+n+. \\\hline - \verb+\oplput(T1,T2){}+ & - Place \verb++ à droite du point situé en - \verb+(T1,T2)+ par rapport au point de référence. \\\hline - \verb+\opmul[P]{n1}{n2}+ & - Affiche le résultat de l'opération \verb+n1*n2+. \\\hline - \verb+\opmul*{n1}{n2}{N}+ & - Calcule \verb+n1*n2+ et place le résultat dans - \verb+N+. \\\hline - \verb+\opneg{n}{N}+ & - Le nombre \verb+N+ reçoit l'opposé de \verb+n+. \\\hline - \verb+\oppower{n}{T}{N}+ & - Calcule \verb+n+ à la puissance \verb+T+ et place le - résultat dans \verb+N+. \\\hline - \verb+\opprint{n}+ & - Affiche le nombre \verb+n+ de façon directe. \\\hline - \verb+\opround{n}{T}{N}+ & - Place dans \verb+N+ la valeur arrondie de \verb+n+ au rang - \verb+T+. \\\hline - \verb+\oprput(T1,T2){}+ & - Place \verb++ à gauche du point situé en - \verb+(T1,T2)+ par rapport au point de référence. \\\hline - \verb+\opset{L}+ & - Effectue une affectation globale des paramètres de \package{xlop} - désignés dans la liste \verb+L+. \\\hline - \verb+\opsetdecimaldigit{n}{T}{N}+ & - Modifie le \verb+T+ième chiffre de la partie décimale de - \verb+N+ pour qu'il soit égal à \verb+n+. \\\hline - \verb+\opsetdigit{n}{T}{N}+ & - Modifie le \verb+T+ième chiffre de \verb+N+ pour qu'il - soit égal à \verb+n+. \\\hline - \verb+\opsetintegerdigit{n}{T}{N}+ & - Modifie le \verb+T+ième chiffre de la partie entière de - \verb+N+ pour qu'il soit égal à \verb+n+. \\\hline - \verb+\opsub[P]{n1}{n2}+ & - Affiche le résultat de l'opération n1-n2. \\\hline - \verb+\opsub*{n1}{n2}{N}+ & - Calcule n1-n2 et place le résultat dans N. \\\hline - \verb+\opunzero{N}+ & - Supprime les zéros non significatifs du nombre \verb+N+. \\\hline - \verb+\opvline(T1,T2){T3}+ & - Trace un trait vertical de longueur \verb+T3+, d'épaisseur - \verb+hrulewidth+ et débutant en \verb+(T1,T2)+ par - rapport au point de référence. \\\hline - \verb+\opwidth{n}{N}+ & - Le nombre \verb+N+ reçoit le nombre de chiffres du nombre - \verb+n+. \\\hline -\end{longtable}\index{macros!table des|)} - -Dans ce tableau, les paramètres : -\begin{itemize} -\item \texttt{n} et \texttt{ni} (où \texttt{i} représente un indice) - indiquent que le paramètre doit être un nombre donné sous forme - décimale ou sous forme d'un nom de variable ; -\item \texttt{N} et \texttt{Ni} (où \texttt{i} représente un indice) - indiquent que le paramètre doit être un nombre donné sous forme d'un - nom de variable ; -\item \texttt{[P]} indique que la macro accepte un paramètre optionnel - permettant de modifier les paramètres de \package{xlop} ; -\item \texttt{T} et \texttt{Ti} (où \texttt{i} représente un indice) - indiquent que le paramètre doit être un nombre donné sous forme - décimale ou sous forme d'un nom de variable mais ne devant pas - excéder la taille des nombres directement acceptables par \TeX{} (en - l'occurrence $-2147483648 \le \mathtt{T} \le 2147483647$). -\end{itemize} - -\section{Liste des paramètres} -\label{sec:Liste des parametres} -\index{parametres@paramètres!table des|(}% -\begingroup -\advance\hoffset by-1.75cm \advance\linewidth by1.75cm -\begin{longtable}{|l|l|p{7cm}|} - \hline - \multicolumn{1}{|c|}{\textbf{Paramètre}} & - \multicolumn{1}{c|}{\textbf{Défaut}} & - \multicolumn{1}{c|}{\textbf{Signification}} \\\hline\hline - \endfirsthead - \hline - \multicolumn{1}{|c|}{\textbf{Paramètre}} & - \multicolumn{1}{c|}{\textbf{Défaut}} & - \multicolumn{1}{c|}{\textbf{Signification}} \\\hline\hline - \endhead - \hline - \multicolumn{3}{|c|}{$\ldots$ à suivre $\ldots$}\\ - \hline - \endfoot - \hline - \endlastfoot - \verb+afterperiodsymbol+ & - \verb+$\ldots$+ & - Symbole utilisé à la suite de la période d'une division. \\\hline - \verb+approxsymbol+ & - \verb+$\approx$+ & - Symbole utilisé comme relation d'égalité approximative dans les - opérations en ligne. \\\hline - \verb+equalsymbol+ & - \verb+{$=$}+ & - Symbole utilisé comme relation d'égalité dans les opérations en - ligne. \\\hline - \verb+addsymbol+ & - \verb-$+$- & - Symbole utilisé comme opérateur d'addition. \\\hline - \verb+subsymbol+ & - \verb+$-$+ & - Symbole utilisé comme opérateur de soustraction. \\\hline - \verb+mulsymbol+ & - \verb+$\times$+ & - Symbole utilisé comme opérateur de multiplication. \\\hline - \verb+divsymbol+ & - \verb+$\div$+ & - Symbole utilisé comme opérateur de division pour les opérations en - ligne. \\\hline - \verb+decimalsepsymbol+ & - \verb+.+ & - Symbole utilisé comme séparateur décimal. \\\hline - \verb+strikedecimalsepsymbol+ & - & - Symbole utilisé pour un séparateur décimal déplacé au niveau du - dividende et du diviseur dans les divisions posées. \\\hline - \verb+shiftintermediarysymbol+ & - \verb+$\cdot$+ & - Symbole utilisé pour montrer les décalages des nombres - intermédiaires dans les multiplications posées. \\\hline - \verb+displayshiftintermediary+ & - \verb+shift+ & - Indique que le caractère de décalage dans les multiplications sera - affiché uniquement pour le décalage supplémentaire (valeur - \verb+shift+), pour tous les décalages (valeur \verb+all+) - ou jamais (valeur \verb+none+). \\\hline - \verb+voperation+ & - \verb+bottom+ & - Type d'alignement vertical d'une opération posée. La - valeur \verb+bottom+ indique que le bas de l'opération sera - au niveau de la ligne de base. La valeur \verb+top+ indique - que la première ligne de l'opération sera sur la ligne de base. La - valeur \verb+center+ indique que l'opération sera centrée - verticalement sur la ligne de base. \\\hline - \verb+voperator+ & - \verb+center+ & - Positionnement vertical de l'opérateur dans les - opérations posées. La valeur \verb+top+ place l'opérateur au - niveau de la première opérande. La valeur \verb+bottom+ place - l'opérateur au niveau de la seconde opérande. La valeur - \verb+center+ place l'opérateur entre les deux - opérandes. \\\hline - \verb+hfactor+ & - \verb+decimal+ & - Type d'alignement des opérandes dans les - multiplications posées. La valeur \verb+decimal+ indique un - alignement sur la virgule. La valeur \verb+right+ indique une - composition au fer à droite. \\\hline - \verb+vruleperiod+ & - \verb+-0.2+ & - Position verticale du trait indiquant la période du quotient - dans les divisions en ligne. \\\hline - \verb+dividendbridge+ & - \verb+false+ & - Indique si le \og pont \fg{} au-dessus du dividende est présent ou - non. \\\hline - \verb+shiftdecimalsep+ & - \verb+both+ & - Indique la façon dont se fait le décalage de virgule au niveau des - opérandes d'une division posée. La valeur \verb+both+ indique - que le décalage doit rendre le diviseur et le dividende - entiers. La valeur \verb+divisor+ indique que le décalage - doit rendre le diviseur entier. La valeur \verb+none+ indique - qu'il n'y aura aucun décalage. \\\hline - \verb+maxdivstep+ & - \verb+10+ & - Nombre d'étapes maximum d'une division. \\\hline - \verb+safedivstep+ & - \verb+50+ & - Nombre d'étapes maximum d'une division lors d'un arrêt sur - période. \\\hline - \verb+period+ & - \verb+false+ & - Indique si la division doit s'arrêter sur une détection de période - ou non. \\\hline - \verb+deletezero+ & - \verb+true+ & - Indique si on affiche (\verb+false+) ou on supprime - (\verb+true+) les zéros non significatifs. \\\hline - \verb+carryadd+ & - \verb+true+ & - Indique si les retenues doivent être affichées pour les additions - posées. \\\hline - \verb+carrysub+ & - \verb+false+ & - Indique si les retenues doivent être affichées pour les - soustractions posées. \\\hline - \verb+offsetcarry+ & - \verb+-0.35+ & - Décalage horizontal pour les retenues dans les - soustractions posées. \\\hline - \verb+style+ & - \verb+display+ & - Indique si l'opération doit être en ligne (\verb+text+) ou - posée (\verb+display+). \\\hline - \verb+displayintermediary+ & - \verb+nonzero+ & - Indique si les résultats intermédiaires doivent être affichés - (\verb+all+) ou seulement les non nuls (\verb+nonzero+) ou - aucun (valeur \verb+none+) dans les multiplications et les - divisions. \\\hline - \verb+lastcarry+ & - \verb+false+ & - Indique si la retenue au niveau d'une absence de chiffre devra - être affichée ou non. \\\hline - \verb+parenthesisnegative+ & - \verb+none+ & - Comportement à adopter pour l'affichage des nombres - négatifs dans les opérations en lignes. La valeur \verb+none+ - les affiche sans parenthèse, \verb+all+ les mettra - systématiquement les nombres négatifs entre parenthèses et - \verb+last+ les mettra entre parenthèses - sauf pour la première valeur d'une expression. \\\hline - \verb+columnwidth+ & - \verb+2ex+ & - Largeur des boîtes contenant un chiffre. \\\hline - \verb+lineheight+ & - \verb+\baselineskip+ & - Hauteur des boîtes contenant un chiffre. \\\hline - \verb+decimalsepwidth+ & - \verb+0pt+ & - Largeur de la boîte contenant le séparateur décimal. \\\hline - \verb+decimalsepoffset+ & - \verb+0pt+ & - Décalage horizontal du séparateur décimal. \\\hline - \verb+hrulewidth+ & - \verb+0.4pt+ & - \'Épaisseur des lignes horizontales. \\\hline - \verb+vrulewidth+ & - \verb+0.4pt+ & - \'Épaisseur des lignes verticales. \\\hline - \verb+behaviorsub+ & - \verb+silent+ & - Comportement de \package{xlop} face à une - soustraction \og impossible \fg{}, c'est-à-dire une soustraction - ayant ses deux opérandes positives avec une seconde opérande - strictement supérieure à la première. La valeur \verb+silent+ - effectuera l'opération en permutant les opérandes de façon - silencieuse. La valeur \verb+warning+ fera de même mais en - émettant un message d'avertissement. Enfin, la valeur - \verb+error+ affichera un message d'erreur et l'opération ne - sera pas effectuée. \\\hline - \verb+country+ & - \verb+french+ & - Indique le comportement des opérations posées en fonction du - pays. L'extension prévoit pour l'instant \verb+french+, - \verb+american+ et \verb+russian+ mais les différentes - façons de présenter les opérations ne sont pas implantées dans la - version 0.2. \\\hline - \verb+operandstyle+ & - & - Style utilisé pour les opérandes. \\\hline - \verb+resultstyle+ & - & - Style utilisé pour les résultats. \\\hline - \verb+remainderstyle+ & - & - Style utilisé pour les restes. \\\hline - \verb+intermediarystyle+ & - & - Style utilisé pour les résultats intermédiaires (nombres - intermédiaires dans une multiplication et nombres à soustraire - dans une division où apparaissent les soustractions - successives). \\\hline - \verb+carrystyle+ & - \verb+\scriptsize+ & - Style utilisé pour les retenues. La valeur par défaut lorsqu'on ne - compile pas sous \LaTeX{} est \verb+\sevenrm+. \\\hline -\end{longtable}\index{parametres@paramètres!table des|)} -\newpage\endgroup - -\chapter{Trucs et astuces} -\label{chap:Trucs et astuces} -\section{Comparaison avec \package{calc} et \package{fp}} -On pourrait croire que \package{xlop} puisse remplacer avantageusement -des extensions telles que -\package{calc}\index{extension!calc}\index{calc} et -\package{fp}\index{extension!fp}\index{fp}. En réalité, c'est un peu -plus compliqué que cela. Bien sûr, \package{xlop} permet des calculs -complexes et sur des nombres comportant un nombre arbitraire de -chiffres mais, contrairement à \package{calc}, il ne permet pas de -gérer directement les unités. La comparaison avec \package{fp} est un -peu plus réaliste mais il ne faut pas perdre de vue que \package{xlop} -peut devenir gourmand en mémoire et en temps de calcul. - -Si vous voulez vraiment réaliser des calculs sur des -longueurs\index{longueur}, vous pouvez toujours utiliser le fait -qu'une affectation d'un registre de longueur à un compteur donnera un -nombre correspondant à cette longueur avec l'unité \texttt{sp}. -\begin{CenterExample}[xrightmargin=0pt] - \newcommand\getsize[2]{% - \dimen0=#1\relax - \count255=\dimen0 - \opcopy{\the\count255}{#2}} - \getsize{1pt}{r}$1\,\mathrm{pt} = \opprint{r}\,\mathrm{sp}$\quad - \getsize{1pc}{r}$1\,\mathrm{pc} = \opprint{r}\,\mathrm{sp}$\quad - \getsize{1in}{r}$1\,\mathrm{in} = \opprint{r}\,\mathrm{sp}$\quad - \getsize{1bp}{r}$1\,\mathrm{bp} = \opprint{r}\,\mathrm{sp}$\quad - \getsize{1cm}{r}$1\,\mathrm{cm} = \opprint{r}\,\mathrm{sp}$\quad - \getsize{1mm}{r}$1\,\mathrm{mm} = \opprint{r}\,\mathrm{sp}$\quad - \getsize{1dd}{r}$1\,\mathrm{dd} = \opprint{r}\,\mathrm{sp}$\quad - \getsize{1cc}{r}$1\,\mathrm{cc} = \opprint{r}\,\mathrm{sp}$\quad - \getsize{1sp}{r}$1\,\mathrm{sp} = \opprint{r}\,\mathrm{sp}$\quad -\end{CenterExample} -N'oubliez cependant pas que le but principal de \package{xlop} est -d'\emph{afficher} automatiquement les opérations. - -Muni de la macro \macro{getsize}, il est possible de réaliser des -calculs sur des longueurs. -\newcommand\getsize[2]{% - \dimen0=#1\relax - \count255=\dimen0 - \opcopy{\the\count255}{#2} -}\par\vspace{-\baselineskip}\noindent -\vbox to0cm{\parindent=0pt\vbox to2.5cm{\vss - \getsize{1cm}{u}% - \getsize{\textwidth}{w}% - \getsize{\textheight}{h}% - \opexpr{w*h/u^2}{S}% - \opround{S}{2}{S}% - \begin{minipage}{4.3cm} - La surface d'empagement est de - \opprint{S}\,$\mathrm{cm}^2$ - \end{minipage}}} -\begin{Verbatim}[xleftmargin=5cm,xrightmargin=0pt] - \getsize{1cm}{u}% - \getsize{\textwidth}{w}% - \getsize{\textheight}{h}% - \opexpr{w*h/u^2}{S}% - \opround{S}{2}{S}% - La surface d'empagement est de - \opprint{S}\,$\mathrm{cm}^2$ -\end{Verbatim} - -\section{Création d'opérations complexes} -\label{sec:Creation d'operations complexes} -L'utilisation des macros de \package{xlop} associées au mécanisme de -boucle de \TeX{} permet de créer des opérations à volonté. Nous ne -donnerons que deux exemples. Le premier est la décomposition d'un -nombre en facteurs premiers, le second est un calcul général de -fraction continue.\index{nombre!premier}% -\index{decomposition@décomposition en nombres premiers} -\begin{Verbatim}[xrightmargin=0pt] - \newcount\primeindex - \newcount\tryindex - \newif\ifprime - \newif\ifagain - \newcommand\getprime[1]{% - \opcopy{2}{P0}% - \opcopy{3}{P1}% - \opcopy{5}{try} - \primeindex=2 - \loop - \ifnum\primeindex<#1\relax - \testprimality - \ifprime - \opcopy{try}{P\the\primeindex}% - \advance\primeindex by1 - \fi - \opadd*{try}{2}{try}% - \ifnum\primeindex<#1\relax - \testprimality - \ifprime - \opcopy{try}{P\the\primeindex}% - \advance\primeindex by1 - \fi - \opadd*{try}{4}{try}% - \fi - \repeat - } - \newcommand\testprimality{% - \begingroup - \againtrue - \global\primetrue - \tryindex=0 - \loop - \opidiv*{try}{P\the\tryindex}{q}{r}% - \opcmp{r}{0}% - \ifopeq \global\primefalse \againfalse \fi - \opcmp{q}{P\the\tryindex}% - \ifoplt \againfalse \fi - \advance\tryindex by1 - \ifagain - \repeat - \endgroup - } -\end{Verbatim} -\newcount\primeindex -\newcount\tryindex -\newif\ifprime -\newif\ifagain -\newcommand\getprime[1]{% - \opcopy{2}{P0}% - \opcopy{3}{P1}% - \opcopy{5}{try} - \primeindex=2 - \loop - \ifnum\primeindex<#1\relax - \testprimality - \ifprime - \opcopy{try}{P\the\primeindex}% - \advance\primeindex by1 - \fi - \opadd*{try}{2}{try}% - \ifnum\primeindex<#1\relax - \testprimality - \ifprime - \opcopy{try}{P\the\primeindex}% - \advance\primeindex by1 - \fi - \opadd*{try}{4}{try}% - \fi - \repeat -} -\newcommand\testprimality{% - \begingroup - \againtrue - \global\primetrue - \tryindex=0 - \loop - \opidiv*{try}{P\the\tryindex}{q}{r}% - \opcmp{r}{0}% - \ifopeq \global\primefalse \againfalse \fi - \opcmp{q}{P\the\tryindex}% - \ifoplt \againfalse \fi - \advance\tryindex by1 - \ifagain - \repeat - \endgroup -} - -Avec ce code, on dispose d'un moyen de créer une liste de nombres -premiers (en l'occurrence les 20~premiers). -\begin{SideBySideExample} - \getprime{20}% - \opprint{P0}, \opprint{P1}, \ldots, - \opprint{P9}, \ldots \opprint{P19}. -\end{SideBySideExample} - -On notera toutefois que ce code est très mauvais, il est excessivement -lent et n'apporte rien par rapport à une approche directe avec des -nombres manipulés par les opérations natives de \TeX{}. Ce n'est -qu'un exemple pédagogique. On notera également l'astuce permettant -d'emboîter deux boucles avec la macro \verb+\testprimality+ -entièrement mise dans un groupe : s'il est nécessaire de rendre les -affectations \verb+\primetrue+ et \verb+\primefalse+ globales, les -opérations de \package{xlop} rendent leurs résultats globaux -directement.\index{affectation globale}% - -Une fois que vous avez votre \og table \fg{} de nombres premiers, vous -pouvez vous en servir pour décomposer un nombre en facteurs -premiers. -\begin{CenterExample}[xrightmargin=0pt] - \newcommand\primedecomp[2][nil]{% - \begingroup - \opset{#1}% - \opcopy{#2}{NbtoDecompose}% - \opabs{NbtoDecompose}{NbtoDecompose}% - \opinteger{NbtoDecompose}{NbtoDecompose}% - \opcmp{NbtoDecompose}{0}% - \ifopeq - Je refuse de d\'ecomposer z\'ero. - \else - \setbox1=\hbox{\opdisplay{operandstyle.1}% - {NbtoDecompose}}% - {\setbox2=\box2{}}% - \count255=1 - \primeindex=0 - \loop - \opcmp{NbtoDecompose}{1}\ifopneq - \opidiv*{NbtoDecompose}{P\the\primeindex}{q}{r}% - \opcmp{0}{r}\ifopeq - \ifvoid2 - \setbox2=\hbox{% - \opdisplay{intermediarystyle.\the\count255}% - {P\the\primeindex}}% - \else - \setbox2=\vtop{% - \hbox{\box2} - \hbox{% - \opdisplay{intermediarystyle.\the\count255}% - {P\the\primeindex}}} - \fi - \opcopy{q}{NbtoDecompose}% - \advance\count255 by1 - \setbox1=\vtop{% - \hbox{\box1} - \hbox{% - \opdisplay{operandstyle.\the\count255}% - {NbtoDecompose}} - }% - \else - \advance\primeindex by1 - \fi - \repeat - \hbox{\box1 - \kern0.5\opcolumnwidth - \opvline(0,0.75){\the\count255.25} - \kern0.5\opcolumnwidth - \box2}% - \fi - \endgroup - } - - \getprime{20}% - \primedecomp[operandstyle.2=\red, - intermediarystyle.2=\red]{252} -\end{CenterExample} -Dans ce code, on notera l'emploi d'un groupe entourant l'ensemble de -la macro pour protéger les modifications de paramètres de -\package{xlop}.\index{parametre@paramètre!modifications locales} -\`A ce propos, on notera également qu'un paramètre vide n'est pas -accepté. C'est tout à fait volontaire, l'auteur de l'extension pensant -qu'un utilisateur tapant des crochets sans rien mettre à l'intérieur -est sans doute en train de commettre une erreur. Pour palier à cette -impossibilité de transmettre un paramètre vide -\index{parametre@paramètre!vide}% -il existe le paramètre particulier \parameter{nil} qui a exactement ce -rôle. - -On notera enfin l'astuce \verb+{\setbox2=\box2}+ qui permet -d'obtenir un registre de boîte vide et les manipulations finales -permettant de représenter la barre verticale de façon lisible. - -Le second exemple permet de calculer une fraction continue du type : -\def\dfrac#1#2{\frac{\displaystyle #1}{\displaystyle #2}} -\[a_0+\dfrac{1}{a_1+\dfrac{1}{a_2+\dfrac{1}{a_3+\cdots}}}\] -en donnant la suite $a_0,a_1,a_2,a_3,\ldots$ à la macro. L'exemple -donne les fractions correspondant au nombre d'or et aux racines -carrées de~2 et~3. -\makeatletter -\begin{CenterExample}[xrightmargin=0pt] - \begingroup - \catcode`\:=12 - \long\gdef\continuedfraction#1#2{% - \let\@mirror\relax - \@for\op@Nb:=#1\do - {% - \ifx\@mirror\relax - \edef\@mirror{\op@Nb}% - \else - \edef\@mirror{\op@Nb,\@mirror}% - \fi - }% - \let\Op@result\relax - \@for\op@Nb:=\@mirror\do - {% - \ifx\Op@result\relax - \opcopy{\op@Nb}{result}% - \else - \opexpr{\op@Nb+1/result}{result}% - \fi - }% - \opcopy{result}{#2}% - } - \endgroup - \continuedfraction{1,1,1,1,1,1,1,1,1,1}{r}\opprint{r}\quad - \continuedfraction{1,2,2,2,2,2,2,2,2,2}{r}\opprint{r}\quad - \continuedfraction{1,1,2,1,2,1,2,1,2,1}{r}\opprint{r} -\end{CenterExample} -\makeatother -Une fois n'est pas coutume, nous avons fait appel à des commandes -\LaTeX{} pour effectuer une boucle. Ce manuel étant composé en -français, le caractère \og \texttt{\string:} \fg{} est actif ce qui -empêche la macro \verb+\@for+ de fonctionner correctement d'où le -groupe où ce caractère reçoit un code de catégorie adéquat. - -\section{Accès direct aux nombres} -\label{sec:Acces direct aux nombres} -Lorsqu'on récupère un nombre dans une variable, on peut le traiter de -multiples façons à l'aide des macros de \package{xlop}. Toutefois, -dans certaines situations, on peut souhaiter construire ses propres -macros ou utiliser des macros externes en passant un tel nombre en -paramètre. - -Passer directement \verb+\opprint{var}+ est inopérant car cette macro -est suffisamment complexe pour induire des effets de bord dans ce -genre de situations. Il devient alors nécessaire d'accéder directement -à ce nombre. Lorsqu'un nombre est mémorisé dans une variable -\verb+var+, \package{xlop} crée une macro -\texttt{$\backslash$Op@var}\index{Opvar@\texttt{\boi {Op\at var}}} -qui contient -ce nombre. On notera le \og O \fg{} majuscule et le \og p \fg{} -minuscule. L'arrobas est là pour rendre cette définition privée -c'est-à-dire qu'il faut faire un effort pour y accéder avec -l'utilisation des macros \macro{makeatletter} et \macro{makeatother} -de \LaTeX{} ou bien en indiquant un code de catégorie égal à~11 -(lettre) pour ce caractère lorsqu'on travaille sous \TeX{}. -\begin{SideBySideExample} - \opcopy{1234}{a}\opcopy{56}{b}% - \opmul*{a}{b}{r}% - \makeatletter - $\nombre{\Op@a} \times - \nombre{\Op@b} = \nombre{\Op@r}$ - \makeatother -\end{SideBySideExample} - -\chapter{Versions futures} -\label{chap:Versions futures} -L'extension \package{xlop} en est à sa version~0.2 qui est -essentiellement une version corrigée de la version~0.1 (première -version publique). La prochaine version sera la~0.3 dont la version -\og stable \fg{} sera alors la version~0.4. - -L'ensemble des spécificités de la version 0.3 n'est pas totalement -arrêté mais il y a déjà plusieurs points prévus : -\begin{itemize} -\item gestion internationale des opérations posées ; -\item opérations en base 2 à 36 ; -\item ajout de fonctions de haut niveau avec les racines - (\macro{oproot} pour les racines quelconques et \macro{opsqrt} pour - la racine carrée), exponentielle, logarithme, fonctions - trigonométriques (directes, inverses, hyperboliques) ; -\item ajout d'une macro permettant de réaliser une écriture formatée, - c'est-à-dire une écriture d'un nombre où les longueurs des parties - entière et décimale seront indiquées (si ces longueurs ne sont pas - celles du nombre, il y aura un débordement ou un remplissage) ; - cette macro existait dans la version~0.1 et permettait - essentiellement d'afficher des nombres avec un alignement sur la - virgule, au fer à droite ou au fer à gauche ; -\item ajout d'une macro permettant les additions à plus de deux - opérandes ; -\item ajout d'un paramètre permettant l'écriture scientifique ou - ingénieur ; -\item possibilité d'écrire un nombre sur plusieurs lignes et/ou en - utilisant un séparateur des milliers ; -\item retenues dans les multiplications ; -\item rendre publics les restes successives d'une division ; -\item les valeurs négatives de \parameter{maxdivstep} et - \parameter{safedivstep} réaliseront un comptage sur les chiffres - décimaux du quotient ; -\item manuel en anglais. -\end{itemize} - -Pour le premier point, seules la division anglo-saxonne, la -multiplication dite russe et la multiplication dite babylonienne sont -en cours d'étude, l'auteur ne connaissant pas les habitudes des autres -pays en la matière. Si vous connaissez d'autres façons de poser les -opérations à part celles présentées dans ce manuel, la division -anglo-saxonne, la multiplication russe (double colonne avec des -divisions par deux sur une colonne et des multiplications par deux sur -l'autre) et la multiplication babylonienne (ou vénitienne qui consiste -à faire une grande grille de multiplication à un chiffre et à effectuer -les sommes finales en diagonale), l'auteur vous sera éternellement -reconnaissant de le contacter à l'adresse : -\begin{verbatim} - Jean-Come.Charpentier@wanadoo.fr -\end{verbatim} -en plaçant le mot \og \texttt{xlop} \fg{} dans le sujet du message. - -Il serait souhaitable d'avoir un manuel du hacker qui expliquerait en -détail le code source. Cet outil pourrait être tout à fait bénéfique -pour que chacun puisse apporter plus facilement des améliorations au -code. Malheureusement, le code actuel fait plus de~\nombre{3900} -lignes et le travail nécessaire risque d'être trop important. -Éventuellement, il pourra y avoir un manuel du hacker expliquant les -spécifications générales du code sans entrer dans trop de détails -techniques. - -%\printindex -\chapter{Index} -\label{chap:index} -\begin{multicols}{2} -\makeatletter -\parindent \z@\relax -\parskip \z@ \@plus.3\p@\relax -\let\item\@idxitem -\makeatother -\renewenvironment{theindex}{}{}% -\input\jobname.ind -\end{multicols} -\end{document} diff --git a/Master/texmf-dist/doc/generic/xlop/history.txt b/Master/texmf-dist/doc/generic/xlop/history.txt index 97ef8d73097..19a54ce28b9 100644 --- a/Master/texmf-dist/doc/generic/xlop/history.txt +++ b/Master/texmf-dist/doc/generic/xlop/history.txt @@ -50,6 +50,11 @@ Correction d'un bogue sur la division 4 janvier 2006 version 0.22 ------------- +-------------- Correction d'un bogue sur l'affichage de la multiplication posée +16 décembre 2010 version 0.23 +--------------- + Correction d'un bogue sur la division + Ajout de \opexport + Manuel en anglais diff --git a/Master/texmf-dist/doc/generic/xlop/xlop-doc-fr.pdf b/Master/texmf-dist/doc/generic/xlop/xlop-doc-fr.pdf new file mode 100644 index 00000000000..b24c2aaca8c Binary files /dev/null and b/Master/texmf-dist/doc/generic/xlop/xlop-doc-fr.pdf differ diff --git a/Master/texmf-dist/doc/generic/xlop/xlop-doc-fr.tex b/Master/texmf-dist/doc/generic/xlop/xlop-doc-fr.tex new file mode 100644 index 00000000000..4dfffa85b5e --- /dev/null +++ b/Master/texmf-dist/doc/generic/xlop/xlop-doc-fr.tex @@ -0,0 +1,2424 @@ +\documentclass[12pt]{report} +\usepackage{manual} +\usepackage[frenchb]{babel} +\usepackage[autolanguage]{numprint} +\fvset{label=source}% français + +\begin{document} +\begin{titlepage} + \null\par\vfill + \begin{center} + \begin{minipage}{0.75\linewidth} + \hrule width\linewidth height2pt depth0pt + \hrule width0pt height3pt depth0pt + \hrule width\linewidth height1pt depth0pt + \hrule width0pt height18pt depth0pt + \begin{center} + \Huge\bfseries XLOP v \fileversion\par\vskip18pt + Manuel de l'utilisateur + \end{center} + \hrule width0pt height6pt depth0pt + \hrule width\linewidth height1pt depth0pt + \hrule width0pt height3pt depth0pt + \hrule width\linewidth height2pt depth0pt + \end{minipage} + \end{center} + \vfill + \begin{center} + Jean-Côme Charpentier\\ + \today + \end{center} + \vfill\null\par +\end{titlepage} +\newpage +\pagenumbering{roman} +\tableofcontents +\newpage +\pagenumbering{arabic} + +\chapter{Présentation} +\label{chap:Présentation} +L'extension \package{xlop} a été développée pour permettre de réaliser +automatiquement des calculs arithmétiques sur des nombres de taille +quelconque et d'afficher les résultats sous forme posée ou en +ligne. Voici un premier exemple permettant de donner un aperçu de la +syntaxe de base : +\begin{SideBySideExample} + \opadd{45,05}{78,4} +\end{SideBySideExample} +Ce premier exemple appelle quelques commentaires qui permettront de +donner une idée sur la façon de manipuler l'extension. + +L'addition est posée \og comme à l'école \fg{} : il s'agit de la +présentation par défaut. On a un alignement sur la virgule des +opérandes et du résultat, le symbole opératoire placé à gauche est +centrée verticalement entre les deux opérandes et le séparateur +décimal est un point malgré le fait d'avoir indiquer les opérandes +avec une virgule dans l'appel de la macro. Enfin, on notera la +présence d'une retenue au dessus de la première opérande. + +Mis à part l'alignement sur la virgule qui est obligatoire pour +l'addition posée, toutes les autres caractéristiques décrites +ci-dessus sont paramétrables. Certaines macros de l'extension et, en +tout cas, toutes les macros affichant les opérations arithmétiques +admettent un argument optionnel qui permettra de contrôler la +présentation. Pour cela, on utilisera une syntaxe \og à la keyval +\fg{} : on spécifie une suite de modifications de paramètres par une +liste d'affectations séparées par des virgules. Une affectation a +une des deux syntaxes possibles ci-dessous : +\begin{verbatim} + = + +\end{verbatim} +la seconde possibilité étant en fait un raccourci pour : +\begin{verbatim} + =true +\end{verbatim} +Dans cette liste d'affectation, on peut faire suivre les virgules par +un ou plusieurs espaces mais il ne faut pas mettre d'espace de part et +d'autre du signe égal ou avant la virgule : un paramètre ou une valeur +pouvant (potentiellement) comporter le caractère espace. + +Ainsi, si l'on veut un séparateur décimal qui soit une virgule, un +symbole opératoire placé en face de la seconde opérande et en +supprimant la présence des retenues, il suffit d'indiquer : +\begin{SideBySideExample} + \opadd[decimalsepsymbol={,}, + voperator=bottom, + carryadd=false]{45.05}{78.4} +\end{SideBySideExample} +On notera la petite astuce consistant à mettre la virgule entre +accolades dans la définition du symbole du séparateur décimal. En +effet, la syntaxe : +\begin{Verbatim}[xrightmargin=0pt] + \opadd[decimalsepsymbol=,,voperator=bottom, + carryadd=false]{45.05}{78.4} +\end{Verbatim} +est fautive : \package{xlop} ne comprenant plus trop bien ce qu'est +cette \og liste \fg{} ! + +Un autre point important quoique moins visible, est que les chiffres +sont disposés à des emplacements très précis. Chaque chiffre est placé +dans une boîte de largeur et de hauteur fixes (paramétrables), le +séparateur décimal est, par défaut, placé dans une boîte de largeur +nulle et toutes les lignes sont régulièrement espacées qu'il y ait ou +non un trait horizontal. Cela permet d'obtenir des alignements +rigoureux et permet également de placer ce que l'on veut à +l'emplacement que l'on veut. +\begin{SideBySideExample} + \psset{xunit=\opcolumnwidth, + yunit=\oplineheight} + \opadd{45.05}{78.4} + \oplput(1.5,3){retenue} + \psline{->}(1,3.15)(-3.25,3.15) +\end{SideBySideExample} +Cet exemple a été réalisé en utilisant l'extension +\package{pstricks}\index{pstricks@\package{pstricks}} + +Nous avons dit précédemment que \package{xlop} était capable de +manipuler des nombres de taille quelconque. Nous reviendrons plus en +détail sur cette possibilité et nous nous contenterons ici de ne donner +qu'un exemple de ce que cela peut offrir. Ne regardez pas trop le +code, les explications seront données plus loin dans ce manuel, pour +l'instant, admirez seulement le résultat ! +\begin{CenterExample}[xrightmargin=0pt] + \opdiv[style=text,period]{1}{49} +\end{CenterExample} + +L'extension \package{xlop} offre quelques autres fonctionnalités. Il +est ainsi possible de manipuler les nombres par l'intermédiaire de +variables, ces variables pouvant être créées par une assignation +simple ou bien comme résultat d'un calcul. On peut également manipuler +les chiffres de façon individuelle : +\begin{SideBySideExample} + \opadd*{45.05}{78.4}{r}% + Le premier chiffre après la virgule de + $45.05+78.4$ est un + \opgetdecimaldigit{r}{1}{d}% + $\opprint{d}$. +\end{SideBySideExample} +effectuer des tests : +\begin{SideBySideExample} + \opadd*{45.05}{78.4}{r}% + La somme $45.05+78.4$ est + \opcmp{r}{100}% + \ifopgt strictement supérieure + \else\ifoplt strictement inférieure + \else égale + \fi\fi + à $100$. +\end{SideBySideExample} +avoir accès à quelques opérations ou fonctions : +\begin{SideBySideExample} + Le pgcd de $182$ et $442$ est + \opgcd{182}{442}{d}$\opprint{d}$ +\end{SideBySideExample} +pouvoir réaliser des calculs complexes sous forme infixe : +\begin{SideBySideExample} + \opexpr{(2+3^2)/(gcd(22,33))}{r}% + $$\frac{2+3^2}{\gcd(22,33)} = + \opprint{r}$$ +\end{SideBySideExample} + +\chapter{Instruction \package{xlop}} +\`A quelques exceptions près qui seront étudiées en temps voulu, les +macros de \package{xlop} peuvent éventuellement avoir un argument +optionnel entre crochets pour modifier localement la valeur des +paramètres de fonctionnement, les autres arguments (qui sont +obligatoires) étant presque toujours des nombres. Les deux sections de +ce chapitre décrivent en détail ce qu'est un nombre pour +\package{xlop} et comment se servir des paramètres. + +\section{Au début était le nombre} +\label{sec:Au début etait le nombre} +\subsection{Taille} +\label{subsec:Taille} +Avant de voir la syntaxe générale d'un nombre, nous allons nous +pencher sur la particularité de \package{xlop} qui est de pouvoir +manipuler des nombres de taille quelconque. + +\index{nombre!taille}Pour être tout à fait précis, la taille théorique +maximum d'un nombre est de $2^{31}-1$ chiffres\index{nombre!limite}. +En pratique, cette limite ne pourra pas être atteinte pour deux +raisons essentielles. La première est qu'une multiplication avec deux +opérandes ayant $2^{25}$ chiffres demanderait plus de $7\,000$ années +de calcul sur l'ordinateur de l'auteur ! La seconde est beaucoup plus +restrictive car elle est liée aux limites de taille des piles de +\TeX{}. Voici un tableau indiquant une compilation sous \TeX{} avec +une multiplication de deux opérandes de même taille sur une machine +Linux, pentium~II~600 et 256~Mo de RAM : +\begin{center} + \begin{tabular}{|l|*{6}{c|}} + \hline + nombre de chiffres & 100 & 200 & 300 & 400 & 425 & 450 \\\hline + temps de compilation (s) & 2 & 8 & 18 & 32 & 36 & crash \\\hline + \end{tabular} +\end{center} +Le \og crash \fg{} indiqué dans le tableau est dû au débordement de la +table de hachage (hash table). \index{hash table}% +\index{depassement de capacite@dépassement de capacité}% +Sous \LaTeX{}, la limite avant crash sera plus réduite. D'autre part, +ces tests ont été effectués sur un fichier minimum : avec un document +source classique, cette limite sera un peu plus basse. Une autre +limite qui risque d'être atteinte relativement rapidement est la +taille du spouleur (spool size). \index{spool size}% +Pour composer ce document qui contient un grand nombre d'appel aux +macros de \package{xlop}, l'auteur a augmenté la taille du spouleur +de~$125\,000$ à~$250\,000$ en éditant la ligne \verb+pool_size+ du +fichier \file{texmf.cnf}. De même, la table de hachage a dû être +augmentée en stipulant la valeur \texttt{1000} au niveau de la ligne +\verb+hash_extra+ du fichier \file{texmf.cnf}. + +\subsection{Syntaxe} +\label{subsec:Syntaxe} +Nous allons présenter cette syntaxe avec la grammaire BNF mais des +explications plus humaines suivront : +\begin{syntaxBNF} + \*nombre* & \{\*signe*\}\*nombre_positif* \alt \*nom* \\ + \*signe* & + \alt - \\ + \*nombre_positif* & \*entier* \alt \*sep*\*entier* \alt \\ + \sameline \*entier*\*sep* \alt \*entier*\*sep*\*entier* \\ + \*sep* & . \alt , \\ + \*entier* & \*chiffre*\{\*chiffre*\} \\ + \*nom* & \*début*\{caractère\} \\ + \*début* & caractère \textnormal{autre que } \*signe*\textnormal{,} + \*sep* \\ + \sameline \textnormal{et} \*chiffre* +\end{syntaxBNF} +\index{syntaxe BNF}\index{BNF}\index{grammaire BNF} + +Le symbole \texttt{caractère} désigne presque n'importe quel caractère +accepté par \TeX{}. Les seules exceptions sont les caractères \verb+%+, +et \verb+#+ qui sont totalement interdits. En fait, les caractères +actifs risquent de poser des problèmes. Par exemple, la définition de +\verb+~+ sous \LaTeX{} empêche ce caractère de pouvoir faire partie +d'un nom. D'autre part, le caractère \verb+\ +conserve sont rôle de +caractère d'échappement, c'est-à-dire que le nom sera celui obtenu +après développement de la macro introduite. Il n'y a aucune autre +contrainte comme le montre le code suivant : +\begin{SideBySideExample} + \newcommand\prefix{a/b} + \opadd*{2}{2}{a/b_{^c}!&$} + \opprint{\prefix_{^c}!&$} +\end{SideBySideExample} +\index{nom de nombre}% +On notera que \verb+a/b_{^c}!&$+ et \verb+\prefix_{^c}!&$+ +représentent très exactement le même nom, si \verb+\prefix+ a la +définition adéquate évidemment. Cette possibilité d'obtenir un nom en +utilisant des macros peut sembler inutile mais il n'en est rien. On +peut ainsi réaliser des boucles\index{boucle} avec des noms tels que +\verb+r1+, \verb+r2+, \ldots, \verb+r+ en utilisant le code +\verb+r\the\cpt+ comme nom où \verb+cpt+ est un compteur au sens +\TeX{}. Le mécanisme des compteurs avec \LaTeX{} donne un code un peu +plus long avec \verb+r\number\value{cpt}+ où \verb+cpt+ est maintenant +un compteur au sens \LaTeX. Nous verrons un exemple d'utilisation de +cette forme à la section~\ref{sec:Creation d'operations complexes} +page~\pageref{sec:Creation d'operations complexes}. + +\index{nombre!valide}En pratique, que signifient toutes ces règles ? +Elles indiquent d'abord qu'un nombre écrit sous forme décimale peut +être précédé par n'importe quelle séquence de signes plus et moins. +Évidemment, le nombre sera négatif lorsqu'il y aura un nombre impair +de signes moins. Ensuite, un nombre ne peut comporter qu'un seul +séparateur décimal qui peut être le point ou la virgule, celui-ci +pouvant être placé n'importe où dans le nombre. Enfin, l'écriture d'un +nombre s'effectue obligatoirement en base~10. Attention : ces règles +signifient également que \verb+-a+ n'est pas valide. + +L'extension utilise quelques noms de façon interne et il est plus +prudent de ne pas commencer un nom de variable par le caractère +\texttt{@}. + +\section{Paramètres de \package{xlop}} +\label{sec:Parametres de xlop} +\index{parametre@paramètre!syntaxe|(} +Les affectations de paramètres restent locales à la macro lorsqu'elles +sont indiquées au niveau de son argument optionnel. Pour rendre de +telles affectations globales, il faut utiliser la macro +\macro{opset}. Par exemple +\begin{Verbatim}[xrightmargin=0pt] + \opset{decimalsepsymbol={,}} +\end{Verbatim} +fera que le symbole du séparateur décimal sera la virgule pour tout le +reste du document, ou, du moins, jusqu'à une prochaine redéfinition +par la macro \verb+\opset+. Dans ce manuel, ce sera le cas à partir de +maintenant.\opset{decimalsepsymbol={,}} + +\subsection{Symboles} +\label{subsecSymboles} +Le paramètre \parameter{afterperiodsymbol} indique le symbole qui suit +l'écriture d'un quotient en ligne lors d'une division avec recherche +de période\index{division!période}. Sa valeur par défaut est +\verb+$\ldots$+ + +Le paramètre \parameter{equalsymbol} indique le symbole utilisé pour +l'égalité. Sa valeur par défaut est \verb+$=$+. En réalité, le +paramètre est défini avec : +\begin{Verbatim}[xrightmargin=0pt] + \opset{equalsymbol={$=$}} +\end{Verbatim} +c'est-à-dire avec des accolades pour protéger le signe égal. Sans les +accolades, il y aurait une erreur à la compilation. On doit procéder +de cette façon lorsque la valeur comporte le signe égal ou une +virgule\index{parametre@paramètre!avec \og = \fg{} ou \og ,\fg} + +Le paramètre \parameter{approxsymbol} indique le symbole utilisé pour +les approximations. Sa valeur par défaut est \verb+$\approx$+. + +Le paramètre \parameter{decimalsepsymbol} indique le symbole utilisé +pour le séparateur décimal. Sa valeur par défaut est le point. + +Les paramètres \parameter{addsymbol}, \parameter{subsymbol}, +\parameter{mulsymbol} et \parameter{divsymbol} indiquent les symboles +utilisés pour les quatre opérations arithmétiques. Les valeurs par +défaut sont respectivement \verb!$+$!, \verb!$-$!, \verb!$\times$! et +\verb!$\div$!. + +\subsection{Présentation générale} +\label{subsec:Presentation generale} +Le paramètre \parameter{voperation} indique la façon dont une +opération posée sera placée par rapport à la ligne de base. Les +valeurs possibles sont \verb+top+, \verb+center+ et \verb+bottom+ +(valeur par défaut). +\begin{SideBySideExample} + top\quad + \opadd[voperation=top]{45}{172}\par + center\quad + \opadd[voperation=center]{45}{172}\par + bottom\quad + \opadd[voperation=bottom]{45}{172} +\end{SideBySideExample} + +Le paramètre \parameter{voperator} indique comment sera placé le +symbole opératoire par rapport aux opérandes. Les valeurs possibles +sont \verb+top+, \verb+center+ (valeur par défaut) et \verb+bottom+. +\begin{SideBySideExample} + top\quad + \opadd[voperator=top]{45}{172}\par + center\quad + \opadd[voperator=center]{45}{172}\par + bottom\quad + \opadd[voperator=bottom]{45}{172} +\end{SideBySideExample} + +Le paramètre \parameter{deletezero} indique si certains nombres d'une +opération doivent être affichés avec ou sans les zéros non +significatifs. Le rôle exact de ce paramètre varie en fonction de +l'opération et nous y reviendrons lors de la présentation des +différentes opérations. + +Le paramètre \parameter{style} indique si l'opération doit être posée +(avec la valeur \verb+display+ qui est la valeur par défaut) ou bien +être affichée en ligne (valeur \verb+text+). On reviendra sur ce +paramètre lors de la présentation de la division car les possibilités +sont alors un peu plus nombreuses. +\begin{SideBySideExample} + \opadd[style=text]{45}{172} +\end{SideBySideExample} +Dans les opérations en ligne, \package{xlop} fait attention à ne pas +composer la formule en mode mathématique de façon directe. Cela permet +de spécifier ce que l'on veut comme dans l'exemple qui suit et c'est +également pour cela qu'il faut indiquer les valeurs classiques des +symboles entre délimiteurs mathématiques. +\begin{SideBySideExample} + \opadd[addsymbol=plus, + equalsymbol=\'egal, + style=text]{42}{172} +\end{SideBySideExample} +Cependant, \package{xlop} introduit exactement les mêmes pénalités de +coupures et exactement les mêmes espacements que pour une formule +mathématique. + +Le paramètre \parameter{parenthesisnegative} indique comment composer +les nombres négatifs dans les opérations en ligne. Les valeurs +possibles sont : +\begin{itemize} +\item \texttt{none} qui compose les nombres négatifs sans parenthèse ; +\item \texttt{all} qui compose les nombres négatifs en les plaçant + entre parenthèses ; +\item \texttt{last} qui compose les nombres négatifs en les plaçant + entre parenthèses s'il ne s'agit pas de la première opérande. +\end{itemize} +\begin{SideBySideExample} + \opadd[style=text, + parenthesisnegative=none] + {-12}{-23}\par + \opadd[style=text, + parenthesisnegative=all] + {-12}{-23}\par + \opadd[style=text, + parenthesisnegative=last] + {-12}{-23} +\end{SideBySideExample} + +\subsection{Dimensions} +\label{subsec:Dimensions} +Dans les opérations posées, les chiffres sont placés dans des boîtes +de dimensions fixées. La largeur est donnée par le paramètre +\parameter{columnwidth} et la hauteur par le paramètre +\parameter{lineheight}. La valeur par défaut du paramètre +\texttt{lineheight} est \verb+\baselineskip+ ce qui fait que les +lignes des opérations seront espacées, par défaut, comme les lignes +d'un paragraphe. La valeur par défaut de \texttt{columnwidth} est de +\texttt{2ex} car la largeur \og normale \fg{} des chiffres aurait +donné des résultats peu lisibles. +\begin{SideBySideExample} + \opadd[columnwidth=0.5em] + {45.89}{127.5} +\end{SideBySideExample} +Ce piètre résultat est dû en partie au fait que la virgule est placé +dans une boîte dont la largeur est contrôlée par le paramètre +\parameter{decimalsepwidth} dont la valeur par défaut est nulle. Un +essai d'amélioration peut être effectué en donnant à ce paramètre la +largeur \og{} normale \fg d'une virgule. +\begin{SideBySideExample} + \opadd[columnwidth=0.5em, + decimalsepwidth=0.27778em] + {45.89}{127.5} +\end{SideBySideExample} +C'est meilleur mais le fait de donner une largeur non nulle à la boîte +contenant le séparateur décimal risque de poser des difficultés si +l'on veut placer des éléments externes : cela va à l'encontre de +l'idée de placer les chiffres dans une grille fixe. Ceci est donc à +éviter en temps normal. + +Les deux paramètres \parameter{columnwidth} et \parameter{lineheight} +correspondent aux deux seules dimensions que l'extension rend +publiques, à savoir respectivement +\verb+\opcolumnwidth+\index{opcolumnwidth@\texttt{$\backslash$opcolumnwidth}} +et +\verb+\oplineheight+\index{oplineheight@\texttt{$\backslash$oplineheight}}. +Il est cependant dangereux de vouloir modifier ces dimensions de façon +directe puisque une modification par voie normale n'a pas pour seule +conséquence d'obtenir une nouvelle valeur pour ces +dimensions. L'extension \package{xlop} a rendu ces dimensions +publiques uniquement pour pouvoir les lire, pas pour les modifier. + +Les deux paramètres suivants permettent de spécifier les largeurs des +traits horizontaux et verticaux tracés par \package{xlop}. Il s'agit +des deux paramètres \parameter{hrulewidth} et \parameter{vrulewidth} +dont la valeur par défaut est \texttt{0.4pt}. + +Ces traits sont composés sans perturber la grille, c'est-à-dire sans +ajouter d'espace vertical. Ainsi, avec des valeurs importantes pour +l'épaisseur, les traits risquent de déborder au niveau des opérandes. +\begin{SideBySideExample} + \opadd[hrulewidth=8pt]{42}{172} +\end{SideBySideExample} + +Il existe également un paramètre permettant de contrôler le décalage +horizontal du séparateur décimal. Il s'agit de +\parameter{decimalsepoffset} dont la valeur par défaut est égale +à~\texttt{-0.35}. Cette valeur par défaut indique une longueur en +prenant \verb+\opcolumnwidth+ comme unité. Un exemple d'utilisation de +ce paramètre sera donné à la section~\ref{sec:Division} +page~\pageref{sec:Division}. + +\subsection{Styles des chiffres} +\label{subsec:Styles des chiffres} +L'extension \package{xlop} distingue cinq types de nombres et y +associe cinq paramètres de style : +\begin{itemize} +\item les opérandes avec \parameter{operandstyle} ; +\item le résultat avec \parameter{resultstyle} ; +\item les restes avec \parameter{remainderstyle} ; +\item les résultats intermédiaires avec \parameter{intermediarystyle} + ; +\item les retenues avec \parameter{carrystyle}. +\end{itemize} +\begin{SideBySideExample} + \opadd[operandstyle=\blue, + resultstyle=\red, + carrystyle=\scriptsize\green] + {45.89}{127.5} +\end{SideBySideExample} +Rappelons que dans ce manuel, nous utilisons l'extension +\package{pstricks}\index{pstricks}. + +\index{parametre@paramètre!indexé|(}% +En réalité, la gestion de ces styles est encore plus puissante car on +peut distinguer les différents nombres d'une même classe. Dans une +même opération, on a plusieurs opérandes et, éventuellement plusieurs +restes et plusieurs nombres intermédiaires. On accède alors au style +de ces nombres individuels en indexant le paramètre de style +correspondant. +\begin{SideBySideExample} + \opadd[operandstyle=\blue, + operandstyle.1=\lightgray, + resultstyle=\red, + carrystyle=\scriptsize\green] + {45.89}{127.5} +\end{SideBySideExample} +Sur cet exemple, on a indiqué que la première opérande devait être +composée avec le style \verb+\lightgray+ et comme rien n'était indiqué +pour la seconde opérande, celle-ci a repris le style de base de sa +classe (donc a été composée avec le style \verb+\blue+). + +Ce mécanisme va encore plus loin car on peut indicer à deux niveaux +les styles des classes opérande, reste et nombre intermédiaire et à un +niveau les styles des classes résultat et retenue pour accéder au +style de chacun des chiffres de ces nombres. Afin de rendre les +indexations plus facile à gérer, un index positif indiquera le rang +d'un chiffre de la partie entière (numérotée de droite à gauche, +l'index~1 correspondant au chiffre des unités) et un index négatif +indiquera le rang d'un chiffre de la partie décimale (numérotée de +gauche à droite, l'index $-1$ correspondant au chiffre des dixièmes). +\begin{SideBySideExample} + \opadd[operandstyle.1.1=\white, + operandstyle.1.-2=\white, + operandstyle.2.3=\white, + resultstyle.2=\white, + deletezero=false] + {045.89}{127.50} +\end{SideBySideExample} +On peut également utiliser une macro à un paramètre comme style. +\begin{SideBySideExample} + \newcommand\hole[1]{$\bullet$} + \opadd[operandstyle.1.1=\hole, + operandstyle.1.-2=\hole, + operandstyle.2.3=\hole, + resultstyle.2=\hole] + {45.89}{127.5} +\end{SideBySideExample} +\index{operation@opération!à trou}% +Lorsque le style est une macro, le chiffre constitue le dernier +argument de cette macro. Voici un exemple plus compliqué et utilisant +l'extension \package{pst-node} de la suite \package{pstricks} : +\begin{SideBySideExample} + \newcommand\OPoval[3]{% + \dimen1=#2\opcolumnwidth + \ovalnode{#1} + {\kern\dimen1 #3\kern\dimen1}} + \opadd[voperation=top, + operandstyle.1.1=\OPoval{A}{0}, + operandstyle.2.2=\OPoval{C}{0.8}] + {45}{172}\qquad + \begin{minipage}[t]{2cm} + \pnode(0,0.2em){B}\ chiffre + \ncarc{->}{A}{B}\par + \pnode(0,0.2em){D}\ nombre + \ncarc{<-}{D}{C} + \end{minipage} +\end{SideBySideExample} + +Comme les chiffres, le séparateur décimal tient compte du style d'un +nombre. Pour accéder au style du séparateur décimal de façon +individuelle, il faut employer l'indice \texttt{d} au lieu des indices +numériques des chiffres. +\begin{SideBySideExample} + \newcommand\hole[1]{\texttt{\_}} + \opmul[intermediarystyle=\hole, + resultstyle=\hole, + resultstyle.d=\white]{2.46}{35.7} +\end{SideBySideExample} +\index{parametre@paramètre!indexé|)}% +\index{parametre@paramètre!syntaxe|)} + +\chapter{Opérations arithmétiques} +\label{chap:Opérations arithmétiques} +\section{Addition} +\label{sec:Addition} +L'addition est gérée par la macro \macro{opadd}. L'addition, +lorsqu'elle est posée, n'affiche que des nombres positifs. Cela va +avoir comme conséquence d'afficher une soustraction lorsqu'une des +opérandes est négative.% +\index{nombre!négatifs dans une opération posée} +\begin{SideBySideExample} + \opadd{-245}{72} +\end{SideBySideExample} +De façon générale, le principe est de poser l'opération qui permet de +retrouver le résultat comme on le ferait à la main. En revanche, +l'affichage en ligne donnera toujours une addition puisqu'on peut +maintenant écrire des nombres négatifs. +\begin{SideBySideExample} + \opadd[style=text]{-245}{72} +\end{SideBySideExample} + Outre les paramètres généraux décrits à la + section~\ref{sec:Parametres de xlop}, la macro \verb+\opadd+ est + sensible aux paramètres \texttt{carryadd}, \texttt{lastcarry} et + \texttt{deletezero}. + +Le paramètre \parameter{carryadd} est un paramètre +booléen\index{parametre@paramètre!booléen} c'est-à-dire n'acceptant +que les valeurs \texttt{true} et \texttt{false}. Comme il d'usage, +l'omission du signe égal et de la partie droite de l'affectation +équivaut à \texttt{=true}. Ce paramètre indique si les retenues +doivent être ou non affichées. Sa valeur par défaut est +\texttt{true}. + +Le paramètre \parameter{lastcarry} est également un paramètre +booléen. Il indique si une retenue sans chiffre correspondant au +niveau des deux opérandes doit être ou non affichée. Sa valeur par +défaut est \texttt{false}. On fera attention au rôle exact de ce +paramètre. Ainsi, si la seconde opérande dans l'exemple qui suit avait +été~15307, la dernière retenue aurait été affichée quelle que soit la +valeur du paramètre \texttt{lastcarry} puisqu'il y aurait eu un +chiffre correspondant au niveau de la seconde opérande. +\begin{SideBySideExample} + \opadd{4825}{5307} +\end{SideBySideExample} +\begin{SideBySideExample} + \opadd[carryadd=false]{4825}{5307} +\end{SideBySideExample} +\begin{SideBySideExample} + \opadd[lastcarry]{4825}{5307} +\end{SideBySideExample} + +Le paramètre \parameter{deletezero} est également un paramètre booléen +et son rôle et d'indiquer si les zéros non significatifs doivent être +supprimés ou non. Sa valeur par défaut est \texttt{true}. Si ce +paramètre vaut \texttt{false}, les opérandes et le résultats auront le +même nombre de chiffres, \package{xlop} ajoutant des zéros non +significatifs pour y parvenir. Les zéros non significatifs des +opérandes ne sont pas supprimés également. +\begin{SideBySideExample} + \opadd{012.3427}{5.2773}\par + \opadd[deletezero=false] + {012.3427}{5.2773} +\end{SideBySideExample} + +Ce paramètre a exactement le même rôle dans l'affichage en ligne que +dans l'affichage posé. +\begin{SideBySideExample} + \opadd[style=text]{02.8}{1.2}\par + \opadd[style=text, + deletezero=false]{02.8}{1.2}\par +\end{SideBySideExample} + +\section{Soustraction} +\label{sec:soustraction} +La soustraction est gérée par la macro \macro{opsub}. La soustraction, +lorsqu'elle est posée, n'affiche que des nombres positifs. Par +conséquence cette macro va afficher une addition lorsqu'une des +opérandes est négative. +\begin{SideBySideExample} + \opsub{-245}{72} +\end{SideBySideExample} +De façon générale, le principe est de poser l'opération qui permet de +retrouver le résultat comme on le ferait à la main. En revanche, +l'affichage en ligne donnera toujours une soustraction puisqu'on peut +maintenant écrire des nombres négatifs. +\begin{SideBySideExample} + \opsub[style=text]{-245}{72} +\end{SideBySideExample} +Ce principe s'applique également lorsque la première opérande est +inférieure à la seconde (cas positif) où on aura une inversion des +opérandes. +\begin{SideBySideExample} + \opsub{1.2}{2.45} +\end{SideBySideExample} +Bien entendu, l'opération en ligne donnera le résultat exact. +\begin{SideBySideExample} + \opsub[style=text]{1.2}{2.45} +\end{SideBySideExample} + + +Outre les paramètres généraux vus à la section~\ref{sec:Parametres de + xlop}, \verb+\opsub+ est sensible à \texttt{carrysub}, +\texttt{lastcarry}, \texttt{offsetcarry}, \texttt{deletezero} et +\texttt{behaviorsub}. + +Le paramètre \parameter{carrysub} est un paramètre booléen +qui indique si les retenues doivent être ou non présentes. Sa valeur +par défaut est \texttt{false} (rappelons que le paramètre +\texttt{carryadd} avait une valeur par défaut égale à \texttt{true}). +\begin{SideBySideExample} + \opsub[carrysub]{1234}{567} +\end{SideBySideExample} + +Dans l'exemple précédent, nous pouvons voir qu'il manque en fait une +retenue au niveau du dernier chiffre de 1234, cette façon de faire +étant assez courante. Néanmoins, on peut contrôler l'affichage de +cette dernière retenue avec le paramètre \parameter{lastcarry}. Ce +paramètre n'a pas tout à fait le même rôle que pour l'addition puisque +la dernière retenue ne sera pas affichée dans le cas où la seconde +opérande n'a pas de chiffre correspondant (alors que pour l'addition, +il fallait que les deux opérandes n'aient pas de chiffres +correspondant). +\begin{SideBySideExample} + \opsub[carrysub,lastcarry]{1234}{567} +\end{SideBySideExample} +On peut noter dans ce dernier cas qu'il est sans doute préférable de +mettre le paramètre \parameter{deletezero} à \texttt{false} pour +obtenir une présentation plus correcte. +\begin{SideBySideExample} + \opsub[carrysub, + lastcarry, + deletezero=false]{1234}{567} +\end{SideBySideExample} + +L'affichage des retenues au niveau des soustractions peut sembler un +peu trop compact. On peut élargir la boîte des chiffres avec le +paramètre \parameter{opcolumnwidth} mais également indiquer le +décalage des retenues avec le paramètre \parameter{offsetcarry}. La +valeur par défaut de ce paramètre est \texttt{-0.35}. +\begin{SideBySideExample} + \opsub[carrysub, + lastcarry, + deletezero=false]{12.34}{5.67} + + \bigskip + \opsub[carrysub, + lastcarry, + columnwidth=2.5ex, + offsetcarry=-0.4, + decimalsepoffset=-3pt, + deletezero=false]{12.34}{5.67} +\end{SideBySideExample} + +Il peut arriver qu'une soustraction de deux nombres positifs, le +premier étant inférieur au second, soit le signe d'une erreur de +l'utilisateur. Dans ce cas, et uniquement dans ce cas, le paramètre +\parameter{behaviorsub} permet d'obtenir un rappel à l'ordre. Les +trois valeurs possibles de ce paramètre sont \texttt{silent} qui est +la valeur par défaut et qui donne le résultat, \texttt{warning} qui +donne également le résultat mais affiche le message d'avertissement : +\begin{Verbatim}[xrightmargin=0pt,frame=none] + xlop warning. Substraction with first operand less than second one + See documentation for further information. +\end{Verbatim} +et enfin \texttt{error} qui affichera le message d'erreur : +\begin{Verbatim}[xrightmargin=0pt,frame=none] + xlop error. See documentation for further information. + Type H for immediate help. + ! Substraction with first operand less than second one. +\end{Verbatim} +et l'opération ne sera pas effectuée. + +\section{Multiplication} +\label{sec:Multiplication} +La multiplication est gérée par la macro \macro{opmul}. +Nous présenterons les paramètres \texttt{hfactor}, +\texttt{displayintermediary}, \texttt{shiftintermediarysymbol}, +\texttt{displayshiftintermediary} et finalement \texttt{deletezero}, +les autres paramètres ayant été vus à la section~\ref{sec:Parametres + de xlop}. + +Le paramètre \parameter{shiftintermediarysymbol} indique quel symbole +sera utilisé (sa valeur par défaut est \verb+$\cdot$+) pour visualiser +les décalages des nombres intermédiaires. Le paramètre +\parameter{displayshiftintermediary} peut prendre les valeurs +\texttt{shift} (valeur par défaut) qui ne montre ce symbole que +lorsque le décalage est supérieur à un rang, \texttt{all} qui indique +que ce symbole de décalage sera systématiquement affiché et +\texttt{none} qui indique que ce symbole ne sera jamais affiché. +\begin{CenterExample}[xrightmargin=0pt] + \opmul[displayshiftintermediary=shift]{453}{1001205}\qquad + \opmul[displayshiftintermediary=all]{453}{1001205}\qquad + \opmul[displayshiftintermediary=none]{453}{1001205} +\end{CenterExample} + +En réalité, le non affichage des nombres intermédiaires nuls est dû à +la valeur par défaut \texttt{none} du paramètre +\parameter{displayintermediary}. La valeur \texttt{all} va afficher +tous les nombres intermédiaires. +\begin{SideBySideExample} + \opmul[displayintermediary=all] + {453}{1001205} +\end{SideBySideExample} +On notera que les nombres intermédiaires nuls sont affichés avec +autant de chiffres que le premier facteur. + +Le paramètre \parameter{displayintermediary} admet la valeur +\texttt{nonzero} qui a le même rôle que la valeur \texttt{none} sauf +dans le cas où le second facteur ne comporte qu'un seul chiffre. +\begin{CenterExample}[xrightmargin=0pt] + \opmul{3.14159}{4}\qquad + \opmul[displayintermediary=nonzero]{3.14159}{4} +\end{CenterExample} + +Le paramètre \parameter{hfactor} permet d'indiquer comment doit se +faire l'alignement des opérandes. La valeur par défaut \texttt{right} +donne une composition au fer à droite tandis que la valeur +\texttt{decimal} donne un alignement au niveau de la virgule. +\begin{CenterExample}[xrightmargin=0pt] + \opmul{3.1416}{12.8}\qquad\opmul[hfactor=decimal]{3.1416}{12.8} +\end{CenterExample} + +Pour la multiplication posée, le paramètre \parameter{deletezero} ne +concerne que les opérandes, le résultat gardant ses éventuels zéros +non significatifs puisque ceux-ci sont nécessaires pour effectuer +correctement le décalage de la virgule lorsqu'on travaille \og à la +main \fg{}. +\begin{CenterExample}[xrightmargin=0pt] + \opmul[deletezero=false]{01.44}{25}\qquad + \opmul{01.44}{25} +\end{CenterExample} +En revanche, dans la multiplication en ligne, ce paramètre retrouve +son comportement normal. +\begin{CenterExample}[xrightmargin=0pt] + \opmul[deletezero=false,style=text]{01.44}{25}\qquad + \opmul[style=text]{01.44}{25} +\end{CenterExample} + +\section{Division} +\label{sec:Division} +L'extension gère la division \og classique \fg{} avec la macro +\macro{opdiv} et la division euclidienne avec la macro +\macro{opidiv}. En raison de sa complexité, la division est l'opération +qui prend en compte le plus de paramètres. + +\subsection{Contrôle de l'arrêt} +\label{subsec:Controle de l'arret} +Dans ce qui suivra, le terme d'\emph{étape} indique l'ensemble des +calculs permettant d'obtenir un chiffre au niveau du quotient. Ce +nombre d'étapes est contrôlé en partie par les paramètres +\parameter{maxdivstep}, \parameter{safedivstep} et \parameter{period}. +En partie seulement car une division classique s'arrêtera +automatiquement lors de l'obtention d'un reste nul, quelles que que +soient les valeurs de ces trois paramètres et une division euclidienne +s'arrêtera sur un quotient entier, sans tenir compte de ces trois +paramètres. +\begin{SideBySideExample} + \opdiv{25}{7} +\end{SideBySideExample} +\begin{SideBySideExample} + \opidiv{25}{7} +\end{SideBySideExample} +Le premier exemple s'arrête en raison de la valeur de +\parameter{maxdivstep} qui est égale, par défaut, à~10. On prendra +garde à ce que le nombre maximum d'étapes peut entraîner des résultats +aberrants lorsqu'il est trop faible. +\begin{SideBySideExample} + \opdiv[maxdivstep=2]{1248}{3} +\end{SideBySideExample} +Le résultat précédent est clairement faux mais \package{xlop} a fait +ce qu'on lui a demandé, en l'occurrence avoir deux chiffres (maximum) +au quotient. + +L'affichage en ligne va également différer selon que la division s'est +arrêtée avec un reste final nul ou non ou selon qu'il s'agit d'une +division classique ou euclidienne. +\begin{SideBySideExample} + \opdiv[style=text]{3.14}{2}\par + \opdiv[style=text]{3.14}{3}\par + \opidiv[style=text]{314}{2}\par + \opidiv[style=text]{314}{3} +\end{SideBySideExample} +On notera l'emploi de \parameter{equalsymbol} ou +\parameter{approxsymbol} selon le cas ainsi que l'affichage avec une +troncature et non un arrondi. Nous verrons comment obtenir un arrondi +à la section~\ref{sec:Operations evoluees} + +L'affichage en ligne de \verb+\opdiv+ tient compte de +\parameter{maxdivstep}. Cela signifie que l'on peut obtenir des +résultats vraiment faux avec des valeurs trop faible de ce paramètre +et, contrairement à l'affichage posé, l'affichage en ligne ne +permettra pas de comprendre ce qu'il s'est passé. +\begin{SideBySideExample} + \opdiv[maxdivstep=2,style=text] + {1248}{3} +\end{SideBySideExample} +Si en plus, le dernier reste calculé est nul, on atteint un summum : +\begin{SideBySideExample} + \opdiv[maxdivstep=1,style=text] + {1208}{3} +\end{SideBySideExample} +puisqu'il n'y a même plus d'approximation ! + +Une division non euclidienne peut également s'arrêter sur la détection +de la survenue d'une période. Pour cela, il suffit de donner la valeur +\texttt{true} au paramètre \parameter{period}\index{division!période}. +\begin{SideBySideExample} + \opdiv[period]{100}{3} +\end{SideBySideExample} + +Pour ne pas avoir à effectuer des comparaisons de chaque reste avec +tous les restes précédents, \package{xlop} calcule dès le départ la +longueur de la période ce qui permet de n'effectuer qu'une seule +comparaison à chaque étape et donc d'accélérer notablement les +calculs\footnote{Je remercie à cette occasion Olivier Viennet pour ses + précisions mathématiques qui ont permis d'implanter correctement ces + calculs.}. Malheureusement, ces calculs se font avec des nombres +directement accessibles à \TeX{} ce qui a pour conséquence de ne pas +pouvoir utiliser d'opérandes dont la valeur absolue excède +$\left\lfloor\frac{2^{31}-1}{10}\right\rfloor = 214748364$. + +Pour ne pas entraîner des calculs trop long, \package{xlop} ne +dépassera pas la valeur du paramètre \parameter{safedivstep} dans les +divisions avec détection de période. Sa valeur par défaut est égale +à~50. Cependant, \package{xlop} signalera le problème. Par exemple si +on demande un tel calcul avec le code : +\begin{Verbatim}[xrightmargin=0pt,frame=none] + \opdiv[period]{1}{289} +\end{Verbatim} +on obtiendra le message d'avertissement : +\begin{Verbatim}[xrightmargin=0pt,frame=none] + xlop warning. Period of division is too big (272 > safedivstep). + Division will stop before reach it. + See documentation for further information. +\end{Verbatim} +qui indique que la période de cette division est de~272 et qu'elle ne +sera donc pas atteinte à cause de la valeur de \texttt{safedivstep}. + +L'affichage en ligne d'une telle division présente quelque +particularités. +\begin{SideBySideExample} + \opdiv[period,style=text]{150}{7} +\end{SideBySideExample} +On obtient donc une égalité au lieu d'une approximation, la présence +d'un trait sous la période et des points de suspension à la suite de +la période. Tous ces éléments peuvent être configurés. Le symbole +d'égalité est donné par le paramètre \parameter{equalsymbol} (valeur +par défaut \verb+{$=$}+), la largeur du trait par le paramètre +\parameter{hrulewidth} (valeur par défaut \texttt{0.4pt}), sa position +verticale par le paramètre \parameter{vruleperiod} (valeur par défaut +\texttt{-0.2}) qui indique un décalage vertical en prenant +\verb+\oplineheight+ comme unité et les points de suspension sont +donnés par le paramètre \parameter{afterperiodsymbol} (valeur par +défaut \verb+$\ldots$+). +\begin{SideBySideExample} + \opdiv[period,style=text, + equalsymbol=$\approx$, + hrulewidth=0.2pt, + vruleperiod=0.7, + afterperiodsymbol=] + {150}{7} +\end{SideBySideExample} + +\subsection{Éléments supplémentaires} +\label{subsec:Elements supplementaires} +Les divisions posées peuvent comporter les soustractions successives +permettant le calcul des restes. Pour \package{xlop}, les nombres qui +sont soustraits sont des nombres intermédiaires donc les différentes +façons de représenter les soustractions utiliserons le paramètre +\parameter{displayintermediary} déjà vu pour la multiplication. La +valeur \texttt{none} (défaut) n'affichera aucune soustraction, la +valeur \texttt{all} affichera toutes les soustractions et la valeur +\texttt{nonzero} affichera les soustractions avec un nombre non nul. +\begin{CenterExample}[xrightmargin=0pt] + \opdiv[displayintermediary=none,voperation=top] + {251}{25}\quad + \opdiv[displayintermediary=nonzero,voperation=top] + {251}{25}\quad + \opdiv[displayintermediary=all,voperation=top] + {251}{25} +\end{CenterExample} + +Lorsqu'on pose une division, on peut dessiner un \og pont \fg{} +au-dessus de la partie du dividende qui sera prise en compte pour la +première étape du calcul. L'extension \package{xlop} permet d'afficher +ce symbole grâce au paramètre booléen \parameter{dividendbridge} +(valeur par défaut \texttt{false}). +\begin{SideBySideExample} + \opdiv[dividendbridge]{1254}{30} +\end{SideBySideExample} + +\subsection{Nombres non entiers et négatifs} +\label{subsec:Nombres non entiers et negatifs} +La présentation d'opérandes non entières est gérée par le paramètre +\parameter{shiftdecimalsep}. Sa valeur par défaut est \texttt{both} et +indique que le séparateur décimal sera décalé pour obtenir un diviseur +et un dividende entiers. La valeur \texttt{divisor} indique qu'il y +aura le décalage nécessaire pour obtenir un diviseur entier et la +valeur \texttt{none} indique qu'il n'y aura aucun décalage. +\begin{CenterExample}[xrightmargin=0pt] + \opdiv[shiftdecimalsep=both]{3.456}{25.6}\quad + \opdiv[shiftdecimalsep=divisor]{3.456}{25.6}\quad + \opdiv[shiftdecimalsep=none]{3.456}{25.6} +\end{CenterExample} + +Un symbole indiqué par le paramètre \parameter{strikedecimalsepsymbol} +est réservé pour montrer l'ancien emplacement de la virgule lorsqu'on +effectue un décalage. La valeur par défaut de ce paramètre est vide ce +qui fait que l'on ne voyait rien sur les exemples précédents. +\begin{CenterExample}[xrightmargin=0pt] + \opset{strikedecimalsepsymbol={\rlap{,}\rule[-1pt]{3pt}{0.4pt}}} + \opdiv[shiftdecimalsep=both]{3.456}{25.6}\quad + \opdiv[shiftdecimalsep=divisor]{3.456}{25.6}\quad + \opdiv[shiftdecimalsep=none]{3.456}{25.6} +\end{CenterExample} + +La présence d'un symbole non vide pour le séparateur décimal barré +peut laisser les zéros non significatifs au niveau des opérandes. +\begin{SideBySideExample} + \opdiv[shiftdecimalsep=divisor, + strikedecimalsepsymbol=% + \hspace{-3pt}\tiny$\times$] + {0.03456}{2.56} +\end{SideBySideExample} + +Comme nous l'avons déjà vu, la macro \macro{opidiv} donne un quotient +entier, cela même si les opérandes sont non entières. Il est un peu +bizarre de vouloir réaliser une division euclidienne sur des nombres +non entiers et la macro \macro{opidiv} sera assez stricte sur sa +présentation. Les paramètres \parameter{maxdivstep}, +\parameter{safedivstep} et \parameter{period} seront sans effet ainsi +que le paramètre \parameter{shiftdecimalsep}, les deux opérandes étant +rendues entières. +\begin{SideBySideExample} + \opidiv[strikedecimalsepsymbol=% + \hspace{-3pt}\tiny$\times$] + {34.57}{7} +\end{SideBySideExample} + +Lorsque les opérandes sont négatives, l'affichage en ligne de +\macro{opidiv} différera des données obtenues avec l'affichage +posée. Le reste sera nécessairement un nombre compris entre zéro +(inclus) et la valeur absolue du diviseur (exclu). +\begin{SideBySideExample} + \opdiv[style=text]{124}{7}\par + \opidiv[style=text]{124}{7}\par + \opidiv[style=text]{124}{-7}\par + \opidiv[style=text]{-124}{7}\par + \opidiv[style=text]{-124}{-7} +\end{SideBySideExample} + +Cette condition sur le reste reste valable même avec un diviseur non +entier. +\begin{SideBySideExample} + \opidiv[style=text]{1.24}{0.7}\par + \opidiv[style=text]{1.24}{-0.7}\par + \opidiv[style=text]{-1.24}{0.7}\par + \opidiv[style=text]{-1.24}{-0.7} +\end{SideBySideExample} + +\chapter{Autres commandes} +\label{chap:Autres commandes} +\section{Macros étoilées} +\label{sec:Macros etoilees} +Les cinq macros vues au chapitre précédent ont une version +étoilée. Ces macros étoilées réalisent le calcul mais ne procèdent à +aucun affichage, le résultat étant stocké dans une variable donnée en +dernier argument. + +Comme ces commandes n'affichent rien, les paramètres ne seront pas +acceptés pour les macros \macro{opadd*}, \macro{opsub*}, +\macro{opmul*} et \macro{opidiv*}. En revanche, les paramètres +\parameter{maxdivestep}, \parameter{safedivstep} et \parameter{period} +influencent les calculs et la macro \macro{opdiv*} acceptera donc un +argument optionnel pour pouvoir en tenir compte. +\begin{SideBySideExample} + \opmul*{2}{2}{a}% + \opmul*{a}{a}{a}\opmul*{a}{a}{a}% + \opadd[style=text]{a}{1} +\end{SideBySideExample} +Pour les macros \macro{opdiv} et \macro{opidiv}, il y aura deux +arguments supplémentaires pour pouvoir recevoir le quotient et le +reste final. +\begin{SideBySideExample} + \opdiv*[maxdivstep=1]{-88}{16}{q}{r}% + \opmul*{q}{16}{bq}% + \opmul[style=text]{16}{q}\par + \opadd[style=text]{bq}{r} +\end{SideBySideExample} + +\section{Entrées-sorties} +\label{sec:Entree-sorties} +La macro \macro{opcopy} recopie son premier argument dans son deuxième +argument. Le premier argument est donc un nombre écrit sous forme +décimale ou via une variable alors que le second sera considérée comme +un nom de variable. + +La macro \macro{opprint} affiche son argument. L'exemple qui suit +utilise le compteur \macro{time} qui indique le nombre de minutes +écoulés depuis minuit. +\begin{SideBySideExample} + \opidiv*{\the\time}{60}{h}{m}% + Il est \opprint{h}~heures et + \opprint{m}~minutes +\end{SideBySideExample} +On verra à la section~\ref{sec:Comparaisons} comment améliorer cet +affichage avec des tests. + +La macro \macro{opdisplay} affiche également un nombre mais en +écrivant chaque chiffre dans une boîte de largeur donnée par +\parameter{columnwidth} et de hauteur donnée par +\parameter{lineheight}. Le style est spécifié par le premier argument +et cette macro accepte un argument optionnel pour permettre de donner +un style particulier aux chiffres individuels. +\begin{SideBySideExample} + \opdisplay[resultstyle.1=\bfseries, + resultstyle.-2=\bfseries] + {resultstyle}{129.192} +\end{SideBySideExample} + +Les macros \macro{oplput} et \macro{oprput} permettent de placer un +objet à un emplacement déterminé. La syntaxe de ces commandes ne +suit pas celle des autres macros de \package{xlop} puisque +l'emplacement est indiqué sous forme de coordonnées entre +parenthèses. Les coordonnées utilisent \macro{opcolumnwidth} et +\macro{oplineheight} comme unités ce qui permet à l'utilisateur de +construire lui-même ses propres \og opérations \fg. +\begin{SideBySideExample} + \psset{xunit=\opcolumnwidth, + yunit=\oplineheight}% + \psgrid[subgriddiv=1,gridlabels=7pt, + griddots=5](0,1)(10,-2) + \oplput(2,0){Bonjour} + \oprput(8,-1){le monde} + $\bullet$ +\end{SideBySideExample} +Sur l'exemple ci-dessus, on peut voir que ces deux macros ne modifient +pas le point de référence. Elles prennent même la précaution d'inhiber +l'espace automatique qui les suit pour qu'il ne soit pas nécessaire de +mettre un \verb+%+ en fin de ligne. + +Les macros \macro{ophline} et \macro{opvline} complète les deux +précédentes pour donner à l'utilisateur les outils lui permettant de +construire ses propres opérations. La macro \macro{ophline} permet de +placer un trait horizontal dont la longueur est donné par le paramètre +qui suit les coordonnées. La macro \macro{opvline} fait de même avec +les traits verticaux. On rappelle que les paramètres +\parameter{hrulewidth} et \parameter{vrulewidth} indiquent les +épaisseurs respectives de ces types de traits. +\begin{CenterExample}[xrightmargin=0pt] + \par\vspace{2\oplineheight} + \oplput(1,2){O}\oplput(2,2){N}\oplput(3,2){E} + \oplput(0,1.5){$+$} + \oplput(1,1){O}\oplput(2,1){N}\oplput(3,1){E} + \ophline(0,0.8){4} + \oplput(1,0){T}\oplput(2,0){W}\oplput(3,0){O} +\end{CenterExample} + +La macro \macro{opexport}\refstepcounter{stuff}\label{macro-opexport} +permet d'exporter un nombre dans une macro. Il s'agit d'un ajout de la +version 0.23 qui est très utile pour faire dialoguer \package{xlop} +avec le monde extérieur. Le premier argument est un nombre au sens +\package{xlop}, c'est-à-dire soit un nombre écrit directement avec des +chiffres, soit un nom de variable. Le nombre sera écrit sous une forme +directement compréhensible par \TeX{} dans le deuxième argument qui +doit donc être un nom de macro. On notera cependant que le séparateur +décimal sera celui désigné par \parameter{decimalsepsymbol} débarrassé +de ses éventuelles accolades. +\begin{SideBySideExample} + \opmul*{5}{3.141592654}{C} + \opexport{C}{\fivepi} + \texttt{\meaning\fivepi} +\end{SideBySideExample} + +On peut se servir de cette macro, par exemple, pour afficher des +nombres calculés par \package{xlop} dans un tableau avec un alignement +décimal ou encore pour initialiser un compteur ou une longueur (ne pas +oublier l'unité dans ce dernier cas). + +\section{Chiffres d'un nombre} +\label{sec:Chiffres d'un nombre} +Les macros \macro{opwidth}, \macro{opintegerwidth} et +\macro{opdecimalwidth} indiquent respectivement le nombre de chiffres +du nombre dans sa totalité, de sa partie entière et de sa partie +décimale. Le premier argument est le nombre sur lequel s'effectue le +comptage et le second argument indique la variable où sera stocké le +résultat. +\begin{SideBySideExample} + \opcopy{123456.1234}{a}% + \opwidth{a}{na}% + \opintegerwidth{a}{ia}% + \opdecimalwidth{a}{da}% + \opprint{a} s'\'ecrit avec \opprint{na} + chiffres (\opprint{ia} en partie + enti\`ere et \opprint{da} en partie + d\'ecimale). +\end{SideBySideExample} + +La macro \macro{opunzero} permet de supprimer les zéros non +significatifs\index{zeros non significatifs@zéros non significatifs} +du nombre passé en argument. +\begin{SideBySideExample} + \opcopy{00150.00250}{a}% + Avant : \opprint{a}\par + \opunzero{a}% + Apr\`es : \opprint{a} +\end{SideBySideExample} + +Les macros \macro{integer} et \macro{opdecimal} donnent respectivement +la partie entière et la partie décimale d'un nombre. +\index{nombre!partie entière}\index{partie entière}% +\index{nombre!partie décimale}\index{partie décimale}% +Le premier argument est le nombre à traiter et le second est la +variable qui contiendra le résultat. +\begin{SideBySideExample} + \opcopy{-37.69911}{a}% + \opinteger{a}{ia}% + \opdecimal{a}{da}% + Partie enti\`ere : \opprint{ia}\par + Partie d\'ecimale : \opprint{da} +\end{SideBySideExample} + +Six macros servent à écrire ou lire un chiffre d'un nombre. On peut +lire ou écrire un chiffre selon son rang dans le nombre, dans sa +partie entière ou dans sa partie décimale. Les chiffres pour le nombre +dans sa totalité ou pour sa partie entière sont numérotés de droite à +gauche et, pour sa partie décimale de gauche à droite. Ainsi, avec le +nombre 1234,56789, le deuxième chiffre est 8, le deuxième chiffre de +sa partie entière est 3 et le deuxième chiffre de sa partie décimale +est 6. Il est alors facile de deviner le rôle respectif des six macros +: +\begin{itemize} +\item \parameter{opgetdigit} ; +\item \parameter{opsetdigit} ; +\item \parameter{opgetintegerdigit} ; +\item \parameter{opsetintegerdigit} ; +\item \parameter{opgetdecimaldigit} ; +\item \parameter{opsetdecimaldigit} ; +\end{itemize} +La syntaxe est la même pour ces six macros. Le premier argument est le +nombre sur lequel doit porter la lecture ou l'écriture, le deuxième +argument est l'index donnant la position du chiffre et le troisième +argument est le nom de la variable qui contiendra le chiffre lu ou +bien ce qui devra être écrit. Si l'index est en dehors du nombre, les +macros de lecture donneront \texttt{0} comme résultat et les macros +d'écriture étendront le nombre pour pouvoir atteindre cet index en +créant des zéros dans les nouvelles positions. + +\section{Comparaisons} +\label{sec:Comparaisons} +Lorsqu'on désire concevoir des macros évoluées, il est très souvent +utile de pouvoir réaliser des tests. Pour cela, \package{xlop} met à +disposition la macro \macro{opcmp} dont les deux arguments sont des +nombres et qui mettra à jour les tests \macro{ifopgt}, \macro{ifopge}, +\macro{ifople}, \macro{ifoplt}, \macro{ifopeq} et \macro{ifopneq} pour +respectivement indiquer que la première opérande est strictement +supérieure, supérieure, inférieure, strictement inférieure, égale ou +différente de la seconde opérande. + +Pour des raisons techniques, \package{xlop} donne des définitions +globales aux six tests précédents. Ceux-ci ne seront donc pas protégés +par les groupes. Comme ces tests sont utilisés par un grand nombre de +macros de \package{xlop}, une conséquence pratique est qu'il faut +\emph{toujours} réaliser les tests \verb+\ifop...+ immédiatement +après le \macro{opcmp}, ou, du moins, avant toute autre utilisation de +macros de \package{xlop} sous peine de bogues éventuels difficiles à +comprendre ! + +On va reprendre la macro d'affichage de l'heure donnée à la +section~\ref{sec:Entree-sorties} mais en vérifiant si l'argument est +compris entre~0 (inclus) et~1440 (exclu) puis en réalisant les tests +nécessaires pour voir si \og heure \fg{} doit être ou non au pluriel +ainsi que \og minute \fg{}. + +\begin{CenterExample}[xrightmargin=0pt] + \newcommand\heure[1]{% + \opcmp{#1}{0}\ifopge + \opcmp{#1}{1440}\ifoplt + \opidiv*{#1}{60}{h}{m}% + \opprint{h} heure% + \opcmp{h}{1}\ifopgt + s% + \fi + \opcmp{m}{0}\ifopneq + \space\opprint{m} minute% + \opcmp{m}{1}\ifopgt + s% + \fi + \fi + \fi\fi + } + \heure{60} -- \heure{1080} -- \heure{1081} -- \heure{1082} +\end{CenterExample} + +\section{Opérations évoluées} +\label{sec:Operations evoluees} +Les macros qui nous restent à voir proviennent soit de commandes +utilisées de façon interne et qu'il aurait été dommage de ne pas +rendre publiques, soit de demandes d'utilisateurs. + +Les macros utilisées de façon interne sont \macro{opgcd}\index{pgcd} +qui donne le pgcd de deux nombres et +\macro{opdivperiod}\index{division!période} qui donne la longueur de +la période d'un quotient de deux nombres. Pour des raisons +d'efficacité, ces macros n'utilisent pas les nombres de \package{xlop} +mais des nombres directement accessibles à \TeX{}. Cela a pour +conséquence que les nombres passés en paramètres dans les deux +premiers arguments ne devront pas dépasser la valeur +\texttt{2147483647} pour \macro{opgcd} et \texttt{214748364} pour +\macro{opdivperiod}. Un message d'avertissement rappellera à l'ordre +en cas de dépassement. Le résultat sera stocké dans la variable +indiqué en troisième paramètre. + +Il y aura également quelques vérifications sur les deux premiers +paramètres. Un pgcd ne peut pas avoir d'argument nul et le calcul de +la longueur d'une période ne pourra pas se faire avec un quotient +nul. D'autre part, si un nombre non entier est passé en paramètre, +seule la partie entière sera prise en compte. +\begin{SideBySideExample} + \opcopy{5376}{a}% + \opcopy{2304}{b}% + \opgcd{a}{b}{gcd(ab)}% + \newcommand\pgcd{% + \mathop{\mathrm{pgcd}}}% + $\pgcd(\opprint{a},\opprint{b}) = + \opprint{gcd(ab)}$ +\end{SideBySideExample} +Si vous voulez vous amuser à trouver de grandes périodes de divisions, +sans entrer dans les détails mathématiques, les carrés de nombres +premiers sont de bons candidats. Par exemple, avec $257^2=66049$ on +trouve : +\begin{SideBySideExample} + \opdivperiod{1}{66049}{p}% + $\frac{1}{66049}$ a une p\'eriode + de longueur $\opprint{p}$. +\end{SideBySideExample} + +Les macros \macro{opcastingoutnines}\index{preuve!par neuf} et +\macro{opcastingoutelevens}\index{preuve!par onze} vont permettre de +composer des preuves par neuf et par onze. L'extension \package{xlop} +ne propose pas directement ces compositions puisqu'elles nécessitent +des traits en diagonal et donc le recours à d'autres extensions. En +réalité, la macro \macro{opcastingoutnines} va faire la somme modulo~9 +des chiffres du premier argument et stockera le résultat dans le +second argument tandis que la macro \macro{opcastingoutelevens} fera +la somme des chiffres de rangs impairs, la somme des chiffres de rangs +pairs puis la différence modulo~11 de ces deux sommes. +\begin{SideBySideExample} + \newcommand\castingoutnines[3]{% + \opcastingoutnines{#1}{cna}% + \opcastingoutnines{#2}{cnb}% + \opmul*{cna}{cnb}{cna*cnb} + \opcastingoutnines{cna*cnb}{cna*cnb}% + \opcastingoutnines{#3}{cn(a*b)}% + \begin{pspicture}(-3.5ex,-3.5ex)% + (3.5ex,3.5ex) + \psline(-3.5ex,-3.5ex)(3.5ex,3.5ex) + \psline(-3.5ex,3.5ex)(3.5ex,-3.5ex) + \rput(-2.75ex,0){\opprint{cna}} + \rput(2.75ex,0){\opprint{cnb}} + \rput(0,2.75ex){\opprint{cna*cnb}} + \rput(0,-2.75ex){\opprint{cn(a*b)}} + \end{pspicture} + } + \castingoutnines{157}{317}{49669} +\end{SideBySideExample} +Incidemment, cet exemple montre que $157\times317\neq49669$ ! La +réponse correcte est \opmul[style=text]{157}{317}. + +Les deux macros suivantes sont très simples. Il s'agit de +\macro{opneg} qui calcul l'opposé de son premier argument et le +sauvegarde dans la variable indiquée par le second argument et de +\macro{opabs} qui réalise la même chose mais avec la valeur absolue. + +La macro \macro{oppower} calcule des puissances entières. Cette macro +demande trois paramètres, le troisième paramètre étant la variable +recevant le résultat du premier paramètre à la puissance le deuxième +paramètre. Le deuxième paramètre doit être un nombre entier. Lorsque +le premier argument est nul, si le deuxième paramètre est nul, le +résultat sera~1, s'il est strictement positif, le résultat sera nul et +s'il est strictement négatif il y aura une erreur et aucun résultat ne +sera fourni. Il n'y a aucune limitation sur le premier paramètre ce +qui peut entraîner quelques problèmes. Par exemple : +\begin{CenterExample}[xrightmargin=0pt] + \opcopy{0.8}{a}\opcopy{-17}{n}% + \oppower{a}{n}{r}% + $\opprint{a}^{\opprint{n}} = \opprint{r}$ +\end{CenterExample} +Avec $0{,}7$ au lieu de $0{,}8$, le problème aurait été encore pire : +\begin{CenterExample}[xrightmargin=0pt] + \opcopy{0.7}{a}\opcopy{-8}{n}% + \oppower{a}{n}{r}% + \opdecimalwidth{r}{dr} + $\opprint{a}^{\opprint{n}}$ a \opprint{dr} chiffres apr\`es la + virgule. +\end{CenterExample} +Cela est dû au fait que lorsque l'exposant est négatif, +\package{xlop} calcule \emph{d'abord} l'inverse du nombre pour +\emph{ensuite} calculer la puissance avec l'opposé de l'exposant. Si +on avait laissé $-17$ au lieu de $-8$ dans l'exemple précédent, les +capacités de \TeX{} auraient été dépassées. + +Les trois macros qui suivent permettent de contrôler la précision des +nombres manipulés. Elles permettent de construire un nombre en donnant +une valeur approchée par défaut, par excès ou un arrondi d'un nombre +donné en précisant le rang où devra se faire l'arrondi. Ces macros +sont respectivement \macro{opfloor}, \macro{opceil} et +\macro{opround}. Elles demandent trois paramètres qui seront dans +l'ordre le nombre de départ, le rang de l'arrondi et le nom de la +variable qui contiendra le résultat. + +Le rang est indiqué par une valeur entière donnant le nombre de +chiffres après la virgule qui doivent être présents. Si le rang est +négatif, l'arrondi se fera avant la virgule. Si le rang positif +indique plus de chiffres que la partie décimale n'en a, des zéros +seront ajoutés. Si le rang négatif indique plus de chiffres que la +partie entière n'en a, l'arrondi restera bloqué pour donner au moins +le premier chiffre du nombre. + +Voici un tableau récapitulatif pour mieux comprendre le fonctionnement +de ces trois macros. +\begin{center} + \opcopy{3838.3838}{a} + \begin{tabular}{|r|l|l|l|} + \hline + \multicolumn{4}{|c|}{\textbf{\texttt{\textbackslash + op\ldots{}\{3838.3838\}\{n\}\{r\}}}}\\\hline + \multicolumn{1}{|c|}{\textbf{\texttt{n}}} & + \multicolumn{1}{c|}{\textbf{\texttt{floor}}} & + \multicolumn{1}{c|}{\textbf{\texttt{ceil}}} & + \multicolumn{1}{c|}{\textbf{\texttt{round}}} \\\hline + \opcopy{6}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\ + \opcopy{4}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\ + \opcopy{3}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\ + \opcopy{0}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\ + \opcopy{-1}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\ + \opcopy{-2}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\ + \opcopy{-6}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\\hline + \end{tabular} + \opcopy{-3838.3838}{a} + \begin{tabular}{|r|l|l|l|} + \hline + \multicolumn{4}{|c|}{\textbf{\texttt{\textbackslash + op\ldots{}\{-3838.3838\}\{n\}\{r\}}}}\\\hline + \multicolumn{1}{|c|}{\textbf{\texttt{n}}} & + \multicolumn{1}{c|}{\textbf{\texttt{floor}}} & + \multicolumn{1}{c|}{\textbf{\texttt{ceil}}} & + \multicolumn{1}{c|}{\textbf{\texttt{round}}} \\\hline + \opcopy{6}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\ + \opcopy{4}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\ + \opcopy{3}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\ + \opcopy{0}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\ + \opcopy{-1}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\ + \opcopy{-2}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\ + \opcopy{-6}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\\hline + \end{tabular} +\end{center} + +\index{expression complexe|(} +La dernière macro qui nous reste à voir est \macro{opexpr} qui permet +de réaliser le calcul d'une expression complexe. Cette macro demande +deux paramètres : le premier est l'expression à calculer donnée sous +forme infixe (la forme habituelle pour un humain) et le second est le +nom de la variable qui contiendra le résultat. + +Initialement, la formule devait être donnée sous forme polonaise +inverse (la notation des calculatrices HP ou du langage PostScript par +exemple) mais un travail commun avec Christophe Jorssen a finalement +abouti à la possibilité de donner l'expression sous une forme plus +agréable pour l'utilisateur. + +Les formules acceptent les opérateurs arithmétiques habituels +\texttt{+}, \texttt{-}, \texttt{*} et \texttt{/} ainsi que l'opérateur +\texttt{:} pour la division euclidienne et \verb+^+ pour +l'exponentiation. L'opérateur \texttt{-} a les deux rôles d'opérateur +binaire de la soustraction et d'opérateur unaire pour l'opposé. +L'opérateur \texttt{+} a également les deux rôles d'opérateur binaire +de l'addition et d'opérateur unaire ne faisant \ldots{} rien ! Les +opérandes sont écrites sous forme décimale ou par l'intermédiaire de +nom de variable cependant, la macro \macro{opexpr} va introduire une +petite restriction sur les noms de variables puisque ceux-ci devront +être différents des noms de fonctions reconnus par cette macro. Les +fonctions accessibles sont : +\begin{itemize} +\item \texttt{abs(a)} ; +\item \texttt{ceil(a,i)} ; +\item \texttt{decimal(a)} ; +\item \texttt{floor(a,i)} ; +\item \texttt{gcd(a,b)} ; +\item \texttt{integer(a)} ; +\item \texttt{mod(a,b)} qui donne le résultat de \texttt{a} modulo + \texttt{b} ; +\item \texttt{rest(a,b)} qui donne le reste de la division de + \texttt{a} par \texttt{b} (la différence entre reste et modulo est + la différence qui existe entre division non euclidienne et division + euclidienne) ; +\item \texttt{round(a,i)}. +\end{itemize} +où les fonctions non décrites ci-dessus font appel aux macros +correspondantes (la fonction \texttt{xxx} faisant appel à la macro +\verb+\opxxx+). Pour les fonctions \texttt{ceil}, \texttt{floor} et +\texttt{round}, le nombre \texttt{i} indique le rang sur lequel doit +se faire l'arrondi. + +La macro \macro{opexpr} accepte un argument optionnel car elle peut +réaliser des divisions et que ces divisions doivent pouvoir être +contrôlées \emph{via} les paramètres \parameter{maxdivstep}, +\parameter{safedivstep} et \parameter{period}. +Notre premier exemple est assez basique : +\begin{CenterExample}[xrightmargin=0pt] + \opexpr{3--gcd(15*17,25*27)*2}{r}% + $3--\gcd(15\times17,25\times27)\times2 = \opprint{r}$ +\end{CenterExample} + +Voici un autre exemple montrant que des données peuvent provenir d'une +macro : +\begin{CenterExample}[xrightmargin=0pt] + \newcommand\try{2}% + \opexpr{\try+1/ + (\try+1/ + (\try+1/ + (\try+1/ + (\try+1/ + (\try)))))}{r} + La fraction continue de base $u_n=2$ vaut \opprint{r} au rang~5. +\end{CenterExample} +\index{expression complexe|)} + +\appendix +\chapter{Aide-mémoire} +\label{chap:Aide-mémoire} +\section{Temps de compilation} +\label{sec:Temps de compilation} +Les temps de compilation ont été mesurés sur une machine à processeur +Pentium~II~600\,MHz ayant 256\,Mo de RAM et tournant sous Linux +(Debian woody)\footnote{En réalité, ces mesures ont été effectuées en + 2004 lors de la sortie de la version 0.2. L'auteur étant fainéant, + il n'a pas repris ces tests avec son matériel actuel (bien plus + performant) !}. Le principe a été de faire un fichier TeX{} minimum +dont le schéma général est donné par : +\begin{verbatim} + \input xlop + \count255=0 + \loop + \ifnum\count255<1000 + + \advance\count255 by1 + \repeat + \bye +\end{verbatim} +Le temps de compilation avec \verb++ vide a été +soustrait des autres tests et seul le temps utilisateur a été pris en +compte. Les résultats sont donnés en millisecondes et sont évidemment +à prendre avec beaucoup de précautions. + +\index{compilation (temps de)|(}\index{temps de calcul|(}% +Le tableau suivant donne le temps de compilation des opérations en +millisecondes. Les opérandes utilisées l'ont été avec une écriture +sous forme de chiffres mais des essais avec des opérandes sous forme +de noms de variable ont montré que les différences étaient vraiment +minimes. + +La première ligne indique le nombre de chiffres des deux +opérandes. Ces nombres ont été construits de la façons suivantes : +\begin{itemize} +\item $\mathrm{A} = 1$ et $\mathrm{B} = 9$ pour un chiffre ; +\item $\mathrm{A} = 12$ et $\mathrm{B} = 98$ pour deux chiffres ; +\item $\mathrm{A} = 123$ et $\mathrm{B} = 987$ pour trois chiffres ; +\item $\mathrm{A} = 12345$ et $\mathrm{B} = 98765$ pour cinq chiffres ; +\item $\mathrm{A} = 1234567890$ et $\mathrm{B} = 9876543210$ pour dix + chiffres ; +\item $\mathrm{A} = 12345678901234567890$ et $\mathrm{B} = + 98765432109876543210$ pour vingt chiffres ; +\end{itemize} +Voici les résultats, quelques commentaires suivront : + +\bigskip\noindent\hbox to\linewidth{\hss + \begin{tabular}{|r|*{6}{l|}} + \cline{2-7} + \multicolumn{1}{l|}{} & + \multicolumn{1}{c|}{1} & + \multicolumn{1}{c|}{2} & + \multicolumn{1}{c|}{3} & + \multicolumn{1}{c|}{5} & + \multicolumn{1}{c|}{10} & + \multicolumn{1}{c|}{20} \\\hline + \verb+\opadd*{A}{B}{r}+ & + 1.1 & 1.4 & 1.6 & 2.1 & 3.3 & 5.8 \\\cline{2-7} + \verb+\opadd*{B}{A}{r}+ & + 1.1 & 1.4 & 1.6 & 2.1 & 3.3 & 5.8 \\\hline + \verb+\opsub*{A}{B}{r}+ & + 1.7 & 2.1 & 2.4 & 3.0 & 4.8 & 8.3 \\\cline{2-7} + \verb+\opsub*{B}{A}{r}+ & + 1.5 & 1.7 & 2.0 & 2.6 & 4.0 & 7.0 \\\hline + \verb+\opmul*{A}{B}{r}+ & + 4.6 & 6.3 & 8.2 & 12.8 & 29.9 & 87.0 \\\cline{2-7} + \verb+\opmul*{B}{A}{r}+ & + 5.0 & 6.6 & 8.5 & 13.2 & 30.3 & 87.8 \\\hline + \verb+\opdiv*{A}{B}{q}{r}+ & + 46.4 & 53.8 & 53.8 & 64.3 & 85.8 & 124.7 \\\cline{2-7} + \verb+\opdiv*{B}{A}{q}{r}+ & + 12.4 & 48.9 & 55.7 & 58.6 & 72.8 & 111.0 \\\hline + \verb+\opdiv*[maxdivstep=5]{A}{B}{q}{r}+ & + 26.8 & 30.0 & 32.6 & 37.6 & 49.5 & 73.5 \\\cline{2-7} + \verb+\opdiv*[maxdivstep=5]{B}{A}{q}{r}+ & + 12.4 & 29.1 & 32.6 & 35.2 & 43.3 & 67.9 \\\hline + \verb+\opidiv*{A}{B}{q}{r}+ & + 10.8 & 12.2 & 13.5 & 16.0 & 22.3 & 35.5 \\\cline{2-7} + \verb+\opidiv*{B}{A}{q}{r}+ & + 11.6 & 13.0 & 14.2 & 16.6 & 23.0 & 36.7 \\\hline + \verb+\opidiv*{A}{2}{q}{r}+ & + 10.7 & 12.0 & 15.3 & 22.3 & 42.9 & 83.0 \\\hline + \end{tabular} + \hss +} +\par\bigskip +Il est normal que l'inversion des opérandes n'ait aucune influence +pour l'addition. Il peut alors sembler anormal qu'elle en ait une pour +la soustraction mais en fait, avoir une seconde opérande supérieure à +la première va entraîner quelques instructions supplémentaires (double +inversion, gestion plus longue du signe du résultat). + +Il est normal que le temps de la division soit supérieur à celui de la +multiplication. Il peut alors sembler anormal que la division ait +l'air de \og rattraper \fg{} son retard. En fait, une multiplication +voit sa complexité fortement augmenter avec la taille des opérandes +mais la division normale est bloquée par le paramètre +\parameter{maxdivstep}. On le voit bien sur l'exemple où on limite ce +maximum à 5~étapes. + +Quelques résultats semblent bizarres. Ainsi, +\verb+\opdiv*{9}{1}{q}{r}+ est anormalement rapide : cela est dû +au fait d'avoir un quotient à un seul chiffre. Plus bizarre encore, +\verb+\opdiv*{123}{987}{q}{r}+ est plutôt rapide. Ici, +l'explication est plus subtile : cela est dû à la présence de nombreux +zéros au quotient. + +Avec des opérandes de taille comparable, la division euclidienne est +très rapide par rapport à la division non euclidienne. Cela est dû au +fait que le quotient n'aura que peu de chiffres (un seul avec tous les +nombres \texttt{A} et \texttt{B}). La dernière ligne du tableau est +plus représentative des temps de compilation que l'on peut obtenir +avec cette opération. + +Toutes ces remarques sont faites pour bien insister sur la difficulté +à évaluer un temps de compilation a priori : il dépend de trop de +paramètres. Cela dit, le tableau permet d'avoir quand même une idée de +ce à quoi il faut s'attendre. +\index{compilation (temps de)|)}\index{temps de calcul|)} + +\clearpage +\section{Liste des macros} +\label{sec:Liste des macros} +\noindent\index{macros!table des|(}% +\begin{longtable}{|l|p{6.3cm}|} + \hline + \multicolumn{1}{|c|}{\textbf{Macro}} & + \multicolumn{1}{c|}{\textbf{Description}} \\\hline\hline + \endfirsthead + \hline + \multicolumn{1}{|c|}{\textbf{Macro}} & + \multicolumn{1}{c|}{\textbf{Description}} \\\hline\hline + \endhead + \hline + \multicolumn{2}{|c|}{$\ldots$ à suivre $\ldots$}\\ + \hline + \endfoot + \hline + \endlastfoot + \verb+\opabs{n}{N}+ & + \verb+N+ reçoit la valeur absolue de \verb+n+. \\\hline + \verb+\opadd[P]{n1}{n2}+ & + Affiche le résultat de l'opération \verb-n1+n2-. \\\hline + \verb+\opadd*{n1}{n2}{N}+ & + Calcule \verb-n1+n2- et place le résultat dans + \verb+N+. \\\hline + \verb+\opcastingoutelevens{n}{N}+ & + Calcule la différence (modulo 11) de la somme des chiffres de rang + impair et de la somme des chiffres de rang pair de \verb+n+ et + place le résultat dans \verb+N+. \\\hline + \verb+\opcastingoutnines{n}{N}+. & + Calcule la somme modulo 9 des chiffres de \verb+n+ et place le + résultat dans \verb+N+. \\\hline + \verb+\opceil{n}{T}{N}+ & + Place dans \verb+N+ la valeur approchée par excès de + \verb+n+ au rang \verb+T+. \\\hline + \verb+\opcmp{n1}{n2}+ & + Compare les nombres \verb+n1+ et \verb+n2+ et réalise la + mise à jour correspondante des tests \verb+\ifopeq+, + \verb+\ifopneq+, \verb+\ifopgt+, \verb+\ifopge+, + \verb+\ifople+ et \verb+\ifoplt+. \\\hline + \verb+\opcopy{n}{N}+ & + Copie le nombre \verb+n+ dans \verb+N+. \\\hline + \verb+\opdecimal{n}{N}+ & + Copie la partie décimale (nombre entier positif) de \verb+n+ + dans \verb+N+. \\\hline + \verb+\opdecimalwidth{n}{N}+ & + Le nombre \verb+N+ reçoit la largeur de la partie décimale du + nombre \verb+n+. \\\hline + \verb+\opdisplay[P]{S}{n}+ & + Affiche le nombre \verb+n+ avec le style \verb+S+ en + plaçant chaque chiffre dans une boîte de largeur + \verb+\opcolumnwidth+ et de hauteur + \verb+\oplineheight+. \\\hline + \verb+\opdiv[P]{n1}{n2}+ & + Affiche le résultat de l'opération n1/n2. \\\hline + \verb+\opdiv*[P]{n1}{n2}{N1}{N2}+ & + Calcule \verb+n1/n2+, place le quotient dans \verb+N1+ et + le reste dans \verb+N2+. \\\hline + \verb+\opdivperiod{T1}{T2}{N}+ & + Calcule la longueur de la période de la division de \verb+T1+ + par \verb+T2+ et place le résultat dans \verb+N+. \\\hline + \verb+\opexport[P]{n}\cmd+ & + Copie le nombre \verb+n+ dans la macro \verb+\cmd+. \\\hline + \verb+\opexpr[P]{F}{N}+ & + \'Évalue la formule \texttt{F} est place le résultat final dans le + nombre \texttt{N}. \\\hline + \verb+\opfloor{n}{T}{N}+ & + Place dans \verb+N+ la valeur approchée par défaut de + \verb+n+ au rang \verb+T+. \\\hline + \verb+\opgcd{T1}{T2}{N}+ & + Calcule le pgcd de \verb+T1+ et \verb+T2+ et place le + résultat dans \verb+N+. \\\hline + \verb+\opgetdecimaldigit{n}{T}{N}+ & + Construit le nombre \verb+N+ avec le seul chiffre situé en + \verb+T+ième position de la partie décimale du nombre + \verb+n+. \\\hline + \verb+\opgetdigit{n}{T}{N}+ & + Construit le nombre \verb+N+ avec le seul chiffre situé en + \verb+T+ième position du nombre \verb+n+. \\\hline + \verb+\opgetintegerdigit{n}{T}{N}+ & + Construit le nombre \verb+N+ avec le seul chiffre situé en + \verb+T+ième position de la partie entière du nombre + \verb+n+. \\\hline + \verb+\ophline(T1,T2){T3}+ & + Trace un trait horizontal de longueur \verb+T3+, d'épaisseur + \verb+hrulewidth+ et débutant en \verb+(T1,T2)+ par + rapport au point de référence. \\\hline + \verb+\opidiv[P]{n1}{n2}+ & + Affiche le résultat de l'opération \verb+n1/n2+ (division + euclidienne, c'est-à-dire avec un quotient entier). \\\hline + \verb+\opidiv*{n1}{n2}{N1}{N2}+ & + Calcule \verb+n1/n2+ (division euclidienne), place le quotient + (entier) dans \verb+N1+ et le reste (compris entre 0 inclus et + \verb+|n2|+ exclu) dans \verb+N2+. \\\hline + \verb+\opinteger{n}{N}+ & + Copie la partie entière (nombre entier positif) de \verb+n+ + dans \verb+N+. \\\hline + \verb+\opintegerwidth{n}{N}+ & + Le nombre \verb+N+ reçoit la longueur de la partie entière du + nombre \verb+n+. \\\hline + \verb+\oplput(T1,T2){}+ & + Place \verb++ à droite du point situé en + \verb+(T1,T2)+ par rapport au point de référence. \\\hline + \verb+\opmul[P]{n1}{n2}+ & + Affiche le résultat de l'opération \verb+n1*n2+. \\\hline + \verb+\opmul*{n1}{n2}{N}+ & + Calcule \verb+n1*n2+ et place le résultat dans + \verb+N+. \\\hline + \verb+\opneg{n}{N}+ & + Le nombre \verb+N+ reçoit l'opposé de \verb+n+. \\\hline + \verb+\oppower{n}{T}{N}+ & + Calcule \verb+n+ à la puissance \verb+T+ et place le + résultat dans \verb+N+. \\\hline + \verb+\opprint{n}+ & + Affiche le nombre \verb+n+ de façon directe. \\\hline + \verb+\opround{n}{T}{N}+ & + Place dans \verb+N+ la valeur arrondie de \verb+n+ au rang + \verb+T+. \\\hline + \verb+\oprput(T1,T2){}+ & + Place \verb++ à gauche du point situé en + \verb+(T1,T2)+ par rapport au point de référence. \\\hline + \verb+\opset{L}+ & + Effectue une affectation globale des paramètres de \package{xlop} + désignés dans la liste \verb+L+. \\\hline + \verb+\opsetdecimaldigit{n}{T}{N}+ & + Modifie le \verb+T+ième chiffre de la partie décimale de + \verb+N+ pour qu'il soit égal à \verb+n+. \\\hline + \verb+\opsetdigit{n}{T}{N}+ & + Modifie le \verb+T+ième chiffre de \verb+N+ pour qu'il + soit égal à \verb+n+. \\\hline + \verb+\opsetintegerdigit{n}{T}{N}+ & + Modifie le \verb+T+ième chiffre de la partie entière de + \verb+N+ pour qu'il soit égal à \verb+n+. \\\hline + \verb+\opsub[P]{n1}{n2}+ & + Affiche le résultat de l'opération n1-n2. \\\hline + \verb+\opsub*{n1}{n2}{N}+ & + Calcule n1-n2 et place le résultat dans N. \\\hline + \verb+\opunzero{N}+ & + Supprime les zéros non significatifs du nombre \verb+N+. \\\hline + \verb+\opvline(T1,T2){T3}+ & + Trace un trait vertical de longueur \verb+T3+, d'épaisseur + \verb+hrulewidth+ et débutant en \verb+(T1,T2)+ par + rapport au point de référence. \\\hline + \verb+\opwidth{n}{N}+ & + Le nombre \verb+N+ reçoit le nombre de chiffres du nombre + \verb+n+. \\\hline +\end{longtable}\index{macros!table des|)} + +Dans ce tableau, les paramètres : +\begin{itemize} +\item \texttt{n} et \texttt{ni} (où \texttt{i} représente un indice) + indiquent que le paramètre doit être un nombre donné sous forme + décimale ou sous forme d'un nom de variable ; +\item \texttt{N} et \texttt{Ni} (où \texttt{i} représente un indice) + indiquent que le paramètre doit être un nombre donné sous forme d'un + nom de variable ; +\item \texttt{[P]} indique que la macro accepte un paramètre optionnel + permettant de modifier les paramètres de \package{xlop} ; +\item \texttt{T} et \texttt{Ti} (où \texttt{i} représente un indice) + indiquent que le paramètre doit être un nombre donné sous forme + décimale ou sous forme d'un nom de variable mais ne devant pas + excéder la taille des nombres directement acceptables par \TeX{} + ($-2147483648 \le \mathtt{T} \le 2147483647$ en l'occurrence). +\end{itemize} + +\newpage +\section{Liste des paramètres} +\label{sec:Liste des parametres} +\index{parametres@paramètres!table des|(}% +\begingroup +\advance\hoffset by-1.75cm \advance\linewidth by1.75cm +\begin{longtable}{|l|l|p{7cm}|} + \hline + \multicolumn{1}{|c|}{\textbf{Paramètre}} & + \multicolumn{1}{c|}{\textbf{Défaut}} & + \multicolumn{1}{c|}{\textbf{Signification}} \\\hline\hline + \endfirsthead + \hline + \multicolumn{1}{|c|}{\textbf{Paramètre}} & + \multicolumn{1}{c|}{\textbf{Défaut}} & + \multicolumn{1}{c|}{\textbf{Signification}} \\\hline\hline + \endhead + \hline + \multicolumn{3}{|c|}{$\ldots$ à suivre $\ldots$}\\ + \hline + \endfoot + \hline + \endlastfoot + \verb+afterperiodsymbol+ & + \verb+$\ldots$+ & + Symbole utilisé à la suite de la période d'une division. \\\hline + \verb+approxsymbol+ & + \verb+$\approx$+ & + Symbole utilisé comme relation d'égalité approximative dans les + opérations en ligne. \\\hline + \verb+equalsymbol+ & + \verb+{$=$}+ & + Symbole utilisé comme relation d'égalité dans les opérations en + ligne. \\\hline + \verb+addsymbol+ & + \verb-$+$- & + Symbole utilisé comme opérateur d'addition. \\\hline + \verb+subsymbol+ & + \verb+$-$+ & + Symbole utilisé comme opérateur de soustraction. \\\hline + \verb+mulsymbol+ & + \verb+$\times$+ & + Symbole utilisé comme opérateur de multiplication. \\\hline + \verb+divsymbol+ & + \verb+$\div$+ & + Symbole utilisé comme opérateur de division pour les opérations en + ligne. \\\hline + \verb+decimalsepsymbol+ & + \verb+.+ & + Symbole utilisé comme séparateur décimal. \\\hline + \verb+strikedecimalsepsymbol+ & + & + Symbole utilisé pour un séparateur décimal déplacé au niveau du + dividende et du diviseur dans les divisions posées. \\\hline + \verb+shiftintermediarysymbol+ & + \verb+$\cdot$+ & + Symbole utilisé pour montrer les décalages des nombres + intermédiaires dans les multiplications posées. \\\hline + \verb+displayshiftintermediary+ & + \verb+shift+ & + Indique que le caractère de décalage dans les multiplications sera + affiché uniquement pour le décalage supplémentaire (valeur + \verb+shift+), pour tous les décalages (valeur \verb+all+) + ou jamais (valeur \verb+none+). \\\hline + \verb+voperation+ & + \verb+bottom+ & + Type d'alignement vertical d'une opération posée. La + valeur \verb+bottom+ indique que le bas de l'opération sera + au niveau de la ligne de base. La valeur \verb+top+ indique + que la première ligne de l'opération sera sur la ligne de base. La + valeur \verb+center+ indique que l'opération sera centrée + verticalement sur la ligne de base. \\\hline + \verb+voperator+ & + \verb+center+ & + Positionnement vertical de l'opérateur dans les + opérations posées. La valeur \verb+top+ place l'opérateur au + niveau de la première opérande. La valeur \verb+bottom+ place + l'opérateur au niveau de la seconde opérande. La valeur + \verb+center+ place l'opérateur entre les deux + opérandes. \\\hline + \verb+hfactor+ & + \verb+decimal+ & + Type d'alignement des opérandes dans les + multiplications posées. La valeur \verb+decimal+ indique un + alignement sur la virgule. La valeur \verb+right+ indique une + composition au fer à droite. \\\hline + \verb+vruleperiod+ & + \verb+-0.2+ & + Position verticale du trait indiquant la période du quotient + dans les divisions en ligne. \\\hline + \verb+dividendbridge+ & + \verb+false+ & + Indique si le \og pont \fg{} au-dessus du dividende est présent ou + non. \\\hline + \verb+shiftdecimalsep+ & + \verb+both+ & + Indique la façon dont se fait le décalage de virgule au niveau des + opérandes d'une division posée. La valeur \verb+both+ indique + que le décalage doit rendre le diviseur et le dividende + entiers. La valeur \verb+divisor+ indique que le décalage + doit rendre le diviseur entier. La valeur \verb+none+ indique + qu'il n'y aura aucun décalage. \\\hline + \verb+maxdivstep+ & + \verb+10+ & + Nombre d'étapes maximum d'une division. \\\hline + \verb+safedivstep+ & + \verb+50+ & + Nombre d'étapes maximum d'une division lors d'un arrêt sur + période. \\\hline + \verb+period+ & + \verb+false+ & + Indique si la division doit s'arrêter sur une détection de période + ou non. \\\hline + \verb+deletezero+ & + \verb+true+ & + Indique si on affiche (\verb+false+) ou on supprime + (\verb+true+) les zéros non significatifs. \\\hline + \verb+carryadd+ & + \verb+true+ & + Indique si les retenues doivent être affichées pour les additions + posées. \\\hline + \verb+carrysub+ & + \verb+false+ & + Indique si les retenues doivent être affichées pour les + soustractions posées. \\\hline + \verb+offsetcarry+ & + \verb+-0.35+ & + Décalage horizontal pour les retenues dans les + soustractions posées. \\\hline + \verb+style+ & + \verb+display+ & + Indique si l'opération doit être en ligne (\verb+text+) ou + posée (\verb+display+). \\\hline + \verb+displayintermediary+ & + \verb+nonzero+ & + Indique si les résultats intermédiaires doivent être affichés + (\verb+all+) ou seulement les non nuls (\verb+nonzero+) ou + aucun (valeur \verb+none+) dans les multiplications et les + divisions. \\\hline + \verb+lastcarry+ & + \verb+false+ & + Indique si la retenue au niveau d'une absence de chiffre devra + être affichée ou non. \\\hline + \verb+parenthesisnegative+ & + \verb+none+ & + Comportement à adopter pour l'affichage des nombres + négatifs dans les opérations en lignes. La valeur \verb+none+ + les affiche sans parenthèse, \verb+all+ les mettra + systématiquement les nombres négatifs entre parenthèses et + \verb+last+ les mettra entre parenthèses + sauf pour la première valeur d'une expression. \\\hline + \verb+columnwidth+ & + \verb+2ex+ & + Largeur des boîtes contenant un chiffre. \\\hline + \verb+lineheight+ & + \verb+\baselineskip+ & + Hauteur des boîtes contenant un chiffre. \\\hline + \verb+decimalsepwidth+ & + \verb+0pt+ & + Largeur de la boîte contenant le séparateur décimal. \\\hline + \verb+decimalsepoffset+ & + \verb+0pt+ & + Décalage horizontal du séparateur décimal. \\\hline + \verb+hrulewidth+ & + \verb+0.4pt+ & + \'Épaisseur des lignes horizontales. \\\hline + \verb+vrulewidth+ & + \verb+0.4pt+ & + \'Épaisseur des lignes verticales. \\\hline + \verb+behaviorsub+ & + \verb+silent+ & + Comportement de \package{xlop} face à une + soustraction \og impossible \fg{}, c'est-à-dire une soustraction + ayant ses deux opérandes positives avec une seconde opérande + strictement supérieure à la première. La valeur \verb+silent+ + effectuera l'opération en permutant les opérandes de façon + silencieuse. La valeur \verb+warning+ fera de même mais en + émettant un message d'avertissement. Enfin, la valeur + \verb+error+ affichera un message d'erreur et l'opération ne + sera pas effectuée. \\\hline + \verb+country+ & + \verb+french+ & + Indique le comportement des opérations posées en fonction du + pays. L'extension prévoit pour l'instant \verb+french+, + \verb+american+ et \verb+russian+ mais les différentes + façons de présenter les opérations ne sont pas implantées dans la + version 0.2. \\\hline + \verb+operandstyle+ & + & + Style utilisé pour les opérandes. \\\hline + \verb+resultstyle+ & + & + Style utilisé pour les résultats. \\\hline + \verb+remainderstyle+ & + & + Style utilisé pour les restes. \\\hline + \verb+intermediarystyle+ & + & + Style utilisé pour les résultats intermédiaires (nombres + intermédiaires dans une multiplication et nombres à soustraire + dans une division où apparaissent les soustractions + successives). \\\hline + \verb+carrystyle+ & + \verb+\scriptsize+ & + Style utilisé pour les retenues. La valeur par défaut lorsqu'on ne + compile pas sous \LaTeX{} est \verb+\sevenrm+. \\\hline +\end{longtable}\index{parametres@paramètres!table des|)} +\newpage\endgroup + +\chapter{Trucs et astuces} +\label{chap:Trucs et astuces} +\section{Comparaison avec \package{calc} et \package{fp}} +On pourrait croire que \package{xlop} puisse remplacer avantageusement +des extensions telles que +\package{calc}\index{extension!calc}\index{calc} et +\package{fp}\index{extension!fp}\index{fp}. En réalité, c'est un peu +plus compliqué que cela. Bien sûr, \package{xlop} permet des calculs +complexes et sur des nombres comportant un nombre arbitraire de +chiffres mais, contrairement à \package{calc}, il ne permet pas de +gérer directement les unités. La comparaison avec \package{fp} est un +peu plus réaliste mais il ne faut pas perdre de vue que \package{xlop} +peut devenir gourmand en mémoire et en temps de calcul. + +Si vous voulez vraiment réaliser des calculs sur des +longueurs\index{longueur}, vous pouvez toujours utiliser le fait +qu'une affectation d'un registre de longueur à un compteur donnera un +nombre correspondant à cette longueur avec l'unité \texttt{sp}. +\begin{CenterExample}[xrightmargin=0pt] + \newcommand\getsize[2]{% + \dimen0=#1\relax + \count255=\dimen0 + \opcopy{\the\count255}{#2}} + \getsize{1pt}{r}$1\,\mathrm{pt}=\opprint{r}\,\mathrm{sp}$\quad + \getsize{1pc}{r}$1\,\mathrm{pc}=\opprint{r}\,\mathrm{sp}$\quad + \getsize{1in}{r}$1\,\mathrm{in}=\opprint{r}\,\mathrm{sp}$\quad + \getsize{1bp}{r}$1\,\mathrm{bp}=\opprint{r}\,\mathrm{sp}$\quad + \getsize{1cm}{r}$1\,\mathrm{cm}=\opprint{r}\,\mathrm{sp}$\quad + \getsize{1mm}{r}$1\,\mathrm{mm}=\opprint{r}\,\mathrm{sp}$\quad + \getsize{1dd}{r}$1\,\mathrm{dd}=\opprint{r}\,\mathrm{sp}$\quad + \getsize{1cc}{r}$1\,\mathrm{cc}=\opprint{r}\,\mathrm{sp}$\quad + \getsize{1sp}{r}$1\,\mathrm{sp}=\opprint{r}\,\mathrm{sp}$\quad +\end{CenterExample} +N'oubliez cependant pas que le but principal de \package{xlop} est +d'\emph{afficher} automatiquement les opérations. + +Muni de la macro \macro{getsize}, il est possible de réaliser des +calculs sur des longueurs. +\newcommand\getsize[2]{% + \dimen0=#1\relax + \count255=\dimen0 + \opcopy{\the\count255}{#2} +}\par\vspace{-\baselineskip}\noindent +\vbox to0cm{\parindent=0pt\vbox to2.5cm{\vss + \getsize{1cm}{u}% + \getsize{\textwidth}{w}% + \getsize{\textheight}{h}% + \opexpr{w*h/u^2}{S}% + \opround{S}{2}{S}% + \begin{minipage}{4.3cm} + La surface d'empagement est de + \opprint{S}\,$\mathrm{cm}^2$ + \end{minipage}}} +\begin{Verbatim}[xleftmargin=5cm,xrightmargin=0pt] + \getsize{1cm}{u}% + \getsize{\textwidth}{w}% + \getsize{\textheight}{h}% + \opexpr{w*h/u^2}{S}% + \opround{S}{2}{S}% + La surface d'empagement est de + \opprint{S}\,$\mathrm{cm}^2$ +\end{Verbatim} + +\section{Création d'opérations complexes} +\label{sec:Creation d'operations complexes} +L'utilisation des macros de \package{xlop} associées au mécanisme de +boucle de \TeX{} permet de créer des opérations à volonté. Nous ne +donnerons que deux exemples. Le premier est la décomposition d'un +nombre en facteurs premiers, le second est un calcul général de +fraction continue.\index{nombre!premier}\index{boucle|(}% +\index{decomposition@décomposition en nombres premiers} +\begin{Verbatim}[xrightmargin=0pt] + \newcount\primeindex + \newcount\tryindex + \newif\ifprime + \newif\ifagain + \newcommand\getprime[1]{% + \opcopy{2}{P0}% + \opcopy{3}{P1}% + \opcopy{5}{try} + \primeindex=2 + \loop + \ifnum\primeindex<#1\relax + \testprimality + \ifprime + \opcopy{try}{P\the\primeindex}% + \advance\primeindex by1 + \fi + \opadd*{try}{2}{try}% + \ifnum\primeindex<#1\relax + \testprimality + \ifprime + \opcopy{try}{P\the\primeindex}% + \advance\primeindex by1 + \fi + \opadd*{try}{4}{try}% + \fi + \repeat + } + \newcommand\testprimality{% + \begingroup + \againtrue + \global\primetrue + \tryindex=0 + \loop + \opidiv*{try}{P\the\tryindex}{q}{r}% + \opcmp{r}{0}% + \ifopeq \global\primefalse \againfalse \fi + \opcmp{q}{P\the\tryindex}% + \ifoplt \againfalse \fi + \advance\tryindex by1 + \ifagain + \repeat + \endgroup + } +\end{Verbatim} +\newcount\primeindex +\newcount\tryindex +\newif\ifprime +\newif\ifagain +\newcommand\getprime[1]{% + \opcopy{2}{P0}% + \opcopy{3}{P1}% + \opcopy{5}{try} + \primeindex=2 + \loop + \ifnum\primeindex<#1\relax + \testprimality + \ifprime + \opcopy{try}{P\the\primeindex}% + \advance\primeindex by1 + \fi + \opadd*{try}{2}{try}% + \ifnum\primeindex<#1\relax + \testprimality + \ifprime + \opcopy{try}{P\the\primeindex}% + \advance\primeindex by1 + \fi + \opadd*{try}{4}{try}% + \fi + \repeat +} +\newcommand\testprimality{% + \begingroup + \againtrue + \global\primetrue + \tryindex=0 + \loop + \opidiv*{try}{P\the\tryindex}{q}{r}% + \opcmp{r}{0}% + \ifopeq \global\primefalse \againfalse \fi + \opcmp{q}{P\the\tryindex}% + \ifoplt \againfalse \fi + \advance\tryindex by1 + \ifagain + \repeat + \endgroup +} + +Avec ce code, on dispose d'un moyen de créer une liste de nombres +premiers (en l'occurrence les 20~premiers). +\begin{SideBySideExample} + \getprime{20}% + \opprint{P0}, \opprint{P1}, \ldots, + \opprint{P9}, \ldots \opprint{P19}. +\end{SideBySideExample} + +On notera toutefois que ce code est très mauvais, il est excessivement +lent et n'apporte rien par rapport à une approche directe avec des +nombres manipulés par les opérations natives de \TeX{}. Ce n'est +qu'un exemple pédagogique. On notera également l'astuce permettant +d'emboîter deux boucles avec la macro \verb+\testprimality+ +entièrement mise dans un groupe : s'il est nécessaire de rendre les +affectations \verb+\primetrue+ et \verb+\primefalse+ globales, les +opérations de \package{xlop} rendent leurs résultats globaux +directement.\index{affectation globale}% + +Une fois que vous avez votre \og table \fg{} de nombres premiers, vous +pouvez vous en servir pour décomposer un nombre en facteurs +premiers. +\begin{CenterExample}[xrightmargin=0pt] + \newcommand\primedecomp[2][nil]{% + \begingroup + \opset{#1}% + \opcopy{#2}{NbtoDecompose}% + \opabs{NbtoDecompose}{NbtoDecompose}% + \opinteger{NbtoDecompose}{NbtoDecompose}% + \opcmp{NbtoDecompose}{0}% + \ifopeq + Je refuse de d\'ecomposer z\'ero. + \else + \setbox1=\hbox{\opdisplay{operandstyle.1}% + {NbtoDecompose}}% + {\setbox2=\box2{}}% + \count255=1 + \primeindex=0 + \loop + \opcmp{NbtoDecompose}{1}\ifopneq + \opidiv*{NbtoDecompose}{P\the\primeindex}{q}{r}% + \opcmp{0}{r}\ifopeq + \ifvoid2 + \setbox2=\hbox{% + \opdisplay{intermediarystyle.\the\count255}% + {P\the\primeindex}}% + \else + \setbox2=\vtop{% + \hbox{\box2} + \hbox{% + \opdisplay{intermediarystyle.\the\count255}% + {P\the\primeindex}}} + \fi + \opcopy{q}{NbtoDecompose}% + \advance\count255 by1 + \setbox1=\vtop{% + \hbox{\box1} + \hbox{% + \opdisplay{operandstyle.\the\count255}% + {NbtoDecompose}} + }% + \else + \advance\primeindex by1 + \fi + \repeat + \hbox{\box1 + \kern0.5\opcolumnwidth + \opvline(0,0.75){\the\count255.25} + \kern0.5\opcolumnwidth + \box2}% + \fi + \endgroup + } + + \getprime{20}% + \primedecomp[operandstyle.2=\red, + intermediarystyle.2=\red]{252} +\end{CenterExample} +Dans ce code, on notera l'emploi d'un groupe entourant l'ensemble de +la macro pour protéger les modifications de paramètres de +\package{xlop}.\index{parametre@paramètre!modifications locales} +\`A ce propos, on notera également qu'un paramètre vide n'est pas +accepté. C'est tout à fait volontaire, l'auteur de l'extension pensant +qu'un utilisateur tapant des crochets sans rien mettre à l'intérieur +est sans doute en train de commettre une erreur. Pour pallier à cette +impossibilité de transmettre un paramètre vide +\index{parametre@paramètre!vide}% +il existe le paramètre particulier \parameter{nil} qui a exactement ce +rôle. +\index{boucle|)} + +On notera enfin l'astuce \verb+{\setbox2=\box2}+ qui permet +d'obtenir un registre de boîte vide et les manipulations finales +permettant de représenter la barre verticale de façon lisible. + +Le second exemple permet de calculer une fraction continue du type : +\def\dfrac#1#2{\frac{\displaystyle #1}{\displaystyle #2}} +\[a_0+\dfrac{1}{a_1+\dfrac{1}{a_2+\dfrac{1}{a_3+\cdots}}}\] +en donnant la suite $a_0,a_1,a_2,a_3,\ldots$ à la macro. L'exemple +donne les fractions correspondant au nombre d'or et aux racines +carrées de~2 et~3. +\makeatletter +\begin{CenterExample}[xrightmargin=0pt] + \begingroup + \catcode`\:=12 + \long\gdef\continuedfraction#1#2{% + \let\@mirror\relax + \@for\op@Nb:=#1\do + {% + \ifx\@mirror\relax + \edef\@mirror{\op@Nb}% + \else + \edef\@mirror{\op@Nb,\@mirror}% + \fi + }% + \let\Op@result\relax + \@for\op@Nb:=\@mirror\do + {% + \ifx\Op@result\relax + \opcopy{\op@Nb}{result}% + \else + \opexpr{\op@Nb+1/result}{result}% + \fi + }% + \opcopy{result}{#2}% + } + \endgroup + \continuedfraction{1,1,1,1,1,1,1,1,1,1,1,1}{r}\opprint{r}\quad + \continuedfraction{1,2,2,2,2,2,2,2,2,2,2,2}{r}\opprint{r}\quad + \continuedfraction{1,1,2,1,2,1,2,1,2,1,2,1}{r}\opprint{r} +\end{CenterExample} +\makeatother +Une fois n'est pas coutume, nous avons fait appel à des commandes +\LaTeX{} pour effectuer une boucle. Ce manuel étant composé en +français, le caractère \og \texttt{\string:} \fg{} est actif ce qui +empêche la macro \verb+\@for+ de fonctionner correctement d'où le +groupe où ce caractère reçoit un code de catégorie adéquat. + +\section{Accès direct aux nombres} +\label{sec:Acces direct aux nombres} +Lorsqu'on récupère un nombre dans une variable, on peut le traiter de +multiples façons à l'aide des macros de \package{xlop}. Toutefois, +dans certaines situations, on peut souhaiter construire ses propres +macros ou utiliser des macros externes en passant un tel nombre en +paramètre. + +Passer directement \verb+\opprint{var}+ est inopérant car cette macro +est suffisamment complexe pour induire des effets de bord dans ce +genre de situations. Il devient alors nécessaire d'accéder directement +à ce nombre. Lorsqu'un nombre est mémorisé dans une variable +\verb+var+, \package{xlop} crée une macro +\texttt{$\backslash$Op@var}\index{Opvar@\texttt{\boi {Op\at var}}} +qui contient +ce nombre. On notera le \og O \fg{} majuscule et le \og p \fg{} +minuscule. L'arrobas est là pour rendre cette définition privée +c'est-à-dire qu'il faut faire un effort pour y accéder avec +l'utilisation des macros \macro{makeatletter} et \macro{makeatother} +de \LaTeX{} ou bien en indiquant un code de catégorie égal à~11 +(lettre) pour ce caractère lorsqu'on travaille sous \TeX{}. +\begin{SideBySideExample} + \opcopy{1234}{a}\opcopy{56}{b}% + \opmul*{a}{b}{r}% + \makeatletter + $\nombre{\Op@a} \times + \nombre{\Op@b} = \nombre{\Op@r}$ + \makeatother +\end{SideBySideExample} + +On notera que cette façon de faire ne fonctionne plus forcément +lorsque le séparateur décimal est entre accolade car la macro +\verb+\opprint{var}+ contiendra ces accolades. Dans ce cas, le plus +simple est de passer par la macro \macro{opexport} décrite à la +page~\pageref{macro-opexport}. + +\chapter{Versions futures} +\label{chap:Versions futures} +L'extension \package{xlop} en est à sa version~0.23 qui n'est qu'une +version déboguée de la version~0.2 qui est elle même +essentiellement une version corrigée de la version~0.1 (première +version publique). La prochaine version sera la~0.3 dont la version +\og stable \fg{} sera alors la version~0.4. + +L'ensemble des spécificités de la version 0.3 n'est pas totalement +arrêté mais il y a déjà plusieurs points prévus : +\begin{itemize} +\item gestion internationale des opérations posées ; +\item opérations en base 2 à 36 ; +\item ajout de fonctions de haut niveau avec les racines + (\macro{oproot} pour les racines quelconques et \macro{opsqrt} pour + la racine carrée), exponentielle, logarithme, fonctions + trigonométriques (directes, inverses, hyperboliques) en passant par + l'extension \package{xfp} qui est une version déboguée (par + l'auteur) de l'extension \package{fp} ; +\item ajout d'une macro permettant de réaliser une écriture formatée, + c'est-à-dire une écriture d'un nombre où les longueurs des parties + entière et décimale seront indiquées (si ces longueurs ne sont pas + celles du nombre, il y aura un débordement ou un remplissage) ; + cette macro existait dans la version~0.1 et permettait + essentiellement d'afficher des nombres avec un alignement sur la + virgule, au fer à droite ou au fer à gauche ; +\item ajout d'une macro permettant les additions à plus de deux + opérandes ; +\item ajout d'un paramètre permettant l'écriture scientifique ou + ingénieur ; +\item possibilité d'écrire un nombre sur plusieurs lignes et/ou en + utilisant un séparateur des milliers ; +\item retenues dans les multiplications ; +\item rendre publics les restes successives d'une division ; +\item les valeurs négatives de \parameter{maxdivstep} et + \parameter{safedivstep} réaliseront un comptage sur les chiffres + décimaux du quotient ; +\item manuel en anglais. +\end{itemize} + +Pour toute demande ou rapport de bogue, l'auteur vous sera +éternellement reconnaissant de le contacter à l'adresse : +\begin{verbatim} + Jean-Come.Charpentier@wanadoo.fr +\end{verbatim} +en plaçant le mot \og \texttt{xlop} \fg{} dans le sujet du message. + +Il serait souhaitable d'avoir un manuel du hacker qui expliquerait en +détail le code source. Cet outil pourrait être tout à fait bénéfique +pour que chacun puisse apporter plus facilement des améliorations au +code. Malheureusement, le code actuel fait plus de~\nombre{4000} +lignes et le travail nécessaire risque d'être trop important. +Éventuellement, il pourra y avoir un manuel du hacker expliquant les +spécifications générales du code sans entrer dans trop de détails +techniques. + +%\printindex +\chapter{Index} +\label{chap:index} +\begin{multicols}{2} +\makeatletter +\parindent \z@\relax +\parskip \z@ \@plus.3\p@\relax +\let\item\@idxitem +\makeatother +\renewenvironment{theindex}{}{}% +\input\jobname.ind +\end{multicols} +\end{document} diff --git a/Master/texmf-dist/doc/generic/xlop/xlop-doc.pdf b/Master/texmf-dist/doc/generic/xlop/xlop-doc.pdf new file mode 100644 index 00000000000..0d3bbaa5900 Binary files /dev/null and b/Master/texmf-dist/doc/generic/xlop/xlop-doc.pdf differ diff --git a/Master/texmf-dist/doc/generic/xlop/xlop-doc.tex b/Master/texmf-dist/doc/generic/xlop/xlop-doc.tex new file mode 100644 index 00000000000..17ec50a0516 --- /dev/null +++ b/Master/texmf-dist/doc/generic/xlop/xlop-doc.tex @@ -0,0 +1,2271 @@ +\documentclass[12pt]{report} +\usepackage{manual} +\usepackage[english]{babel} +\usepackage[autolanguage]{numprint} +\usepackage{dcolumn} + +\newcommand*\boi{\textbackslash} +\newcommand*\at{@} +\fvset{label=source}% english + +\renewcommand\parameter[1]{\texttt{#1}\index{#1@\texttt{#1}}% + \index{parameter!\texttt{#1}}} + +\begin{document} +\begin{titlepage} + \null\par\vfill + \begin{center} + \begin{minipage}{0.75\linewidth} + \hrule width\linewidth height2pt depth0pt + \hrule width0pt height3pt depth0pt + \hrule width\linewidth height1pt depth0pt + \hrule width0pt height18pt depth0pt + \begin{center} + \Huge\bfseries XLOP v \fileversion\par\vskip18pt + User Manual + \end{center} + \hrule width0pt height6pt depth0pt + \hrule width\linewidth height1pt depth0pt + \hrule width0pt height3pt depth0pt + \hrule width\linewidth height2pt depth0pt + \end{minipage} + \end{center} + \vfill + \begin{center} + Jean-Côme Charpentier\\ + \today + \end{center} + \vfill\null\par +\end{titlepage} +\newpage +\pagenumbering{roman} +\tableofcontents +\newpage +\pagenumbering{arabic} + +\chapter{Overview} +\label{chap:Présentation} +The \package{xlop} package is intended to make automatic arithmetic +operation on arbitrary sized numbers and to display result either on +display mode or inline mode. Here is a first exemple for an overview +of the syntax: +\begin{SideBySideExample} + \opadd{45,05}{78,4} +\end{SideBySideExample} +We comment this first example in order to give an idea about how use +\package{xlop}. +Addition is displayed ``like in school'': this is the default +displaying. We have an alignment on dots (operand's dot and result's +dot), operator symbol is put on the left and it is vertically centered +between the operands, and the decimal separator is a dot even though we +have specified operands with comma. Finally, note that there is a +carry above the first operand. + +Alignment on dot is obligatory. The other points above are deal with +options. Many macros accept an optional argument which controls some +aspects of displaying or computing operation. For that, we use a +``keyval-like'' syntax: we specify a sequence of parameter's +modifications through an affectation's comma separated sequence. One +affectation has one of the two possible syntax below: +\begin{verbatim} + = + +\end{verbatim} +the second one is a shorthand for: +\begin{verbatim} + =true +\end{verbatim} +In this affectation sequence, we can put space(s) after comma. But +don't put space around the equal sign nor before comma: if you put +space(s) here, that means that parameter name or value has a space. + +So, if you want a comma as decimal separator , an operator symbol side +by side with the second operand, and no carry, you have just to say: +\begin{SideBySideExample} + \opadd[decimalsepsymbol={,}, + voperator=bottom, + carryadd=false]{45.05}{78.4} +\end{SideBySideExample} +Note the trick which consists to put the comma between braces in the +decimal separator symbol definition. In fact, if you say: +\begin{Verbatim}[xrightmargin=0pt] + \opadd[decimalsepsymbol=,,voperator=bottom, + carryadd=false]{45.05}{78.4} +\end{Verbatim} +\package{xlop} drives mad! It don't understand what is this sort of +list! + +Another important point, though it is less apparent, is that the +figures are put in very precise places. Each figure is put in a box of +fixed width and fixed height (user can change these values), decimal +separator is put in a null-width box (by default), and the lines have +a regular interspace (with or without horizontal rule). This allows +exact spacing and to place what we want where we want. +\begin{SideBySideExample} + \psset{xunit=\opcolumnwidth, + yunit=\oplineheight} + \opadd{45.05}{78.4} + \oplput(1.5,3){carry} + \psline{->}(1,3.15)(-3.25,3.15) +\end{SideBySideExample} +This example uses package +\package{pstricks}\index{pstricks@\package{pstricks}} + +We have said that \package{xlop} package is able to deal with +arbitrary sized numbers. We come again about this subject and, for +now, we just give an example which shows what is possible. Don't look +at the code, some explanations will be given later in this manual, for +now just admire the result! +\begin{CenterExample}[xrightmargin=0pt] + \opdiv[style=text,period]{1}{49} +\end{CenterExample} + +The package \package{xlop} provides some other features. It is +possible to manipulate numbers through variables. These variables can +be created with an assignation or as a computation result. You can +also manipulate the figures individually: +\begin{SideBySideExample} + \opadd*{45.05}{78.4}{r}% + The first figure after dot of + $45.05+78.4$ is + \opgetdecimaldigit{r}{1}{d}% + $\opprint{d}$. +\end{SideBySideExample} +you can make tests: +\begin{SideBySideExample} + \opadd*{45.05}{78.4}{r}% + The sum $45.05+78.4$ is + \opcmp{r}{100}% + \ifopgt greater than + \else\ifoplt less than + \else equal to + \fi\fi + $100$. +\end{SideBySideExample} +you can use some operations and some functions: +\begin{SideBySideExample} + gcd of $182$ and $442$ is + \opgcd{182}{442}{d}$\opprint{d}$ +\end{SideBySideExample} +you can compute complex expression in infix form: +\begin{SideBySideExample} + \opexpr{(2+3^2)/(gcd(22,33))}{r}% + $$\frac{2+3^2}{\gcd(22,33)} = + \opprint{r}$$ +\end{SideBySideExample} + +\chapter{\package{xlop} Instructions} +Except some macros which will be examined later, the \package{xlop}'s +macros can have an optional argument between squared braces in order +to localy modify parameter's values. The other arguments (mandatory) +are (nearly) always numbers. The two sections of this chapter describe +in details what is a number for \package{xlop} and how use parameters. + +\section{In the Beginning Was the Number} +\label{sec:Au début etait le nombre} +\subsection{Size} +\label{subsec:Taille} +Before we see the general syntax of number, we examin the very +particular \package{xlop} feature: the ability to deal with arbitrary +sized number. + +\index{number!size}To be precise, the theoric maximum size of a number +is $2^{31}-1$ digits\index{number!limit}. In practice, this limit +can't be reached for two essential reasons. The first one is that a +multiplication with two numbers with $2^{25}$~digits needs more than +$7\,000$ years to be performed on the author computer! The second one +is more restrictive because it is linked to \TeX{} stack size limits. +Here is a table showing a \TeX{} compilation for a multiplication with +two operands of same size, on a linux computer, pentium~II~600 and +256~Mb RAM:\footnote{In fact it was the author computer in 2004. The + actual author computer is \emph{more} powerfull but the author is + lazy, and he have not remake the tests!} +\begin{center} + \begin{tabular}{|l|*{6}{c|}} + \hline + number of digits & 100 & 200 & 300 & 400 & 425 & 450 \\\hline + compilation time (s) & 2 & 8 & 18 & 32 & 36 & crash \\\hline + \end{tabular} +\end{center} +The ``crash'' in the table is due to an overstack for hash table. +\index{hash table}% +\index{overflow}% +On \LaTeX{}, the limit before crash will be reduced. These tests are +made on a minimal file. With a typical document, this limit will be +reduced too. The spool size is another limit quickly reached. +\index{spool size}% +To typeset this document which contain many calls to the +\package{xlop} macros, the author has grown up the spool size +to~$250000$ ($125\,000$ was insufficient) editing the line +\verb+pool_size+ in the \file{texmf.cnf} file. Also, the author has +grown up the hash table to~\texttt{1000} in the line +\verb+hash_extra+. + +\subsection{Syntax} +\label{subsec:Syntaxe} +Now we present the syntax using the BNF grammar. There will be human +explanations later: +\begin{syntaxBNF} + \*number* & \{\*sign*\}\*positive* \alt \*name* \\ + \*sign* & + \alt - \\ + \*positive* & \*integer* \alt \*sep*\*integer* \alt \\ + \sameline \*integer*\*sep* \alt \*integer*\*sep*\*integer* \\ + \*sep* & . \alt , \\ + \*integer* & \*digit*\{\*digit*\} \\ + \*name* & \*start*\{character\} \\ + \*start* & character \textnormal{except } \*sign*\textnormal{,} + \*sep* \\ + \sameline \textnormal{, and } \*digit* +\end{syntaxBNF} +\index{syntax!BNF}\index{BNF grammar} + +The \texttt{character} symbol means nearly any character accepted by +\TeX{}. The exceptions are characters \verb+%+ and \verb+#+ which are +completely prohibited. In fact, the use of active characters is +risked. For instance, on \LaTeX{}, the \verb+~+ definition prohibits the +use of it inside a variable name. In the other hand, the \verb+\ +is +always the escape char, that is, the variable name will be the name +\emph{after} all is expanded. There isn't any other restraint as the +following code show it: +\begin{SideBySideExample} + \newcommand\prefix{a/b} + \opadd*{2}{2}{a/b_{^c}!&$} + \opprint{\prefix_{^c}!&$} +\end{SideBySideExample} +\index{number!name}% +Note particullary that \verb+a/b_{^c}!&$+ and \verb+\prefix_{^c}!&$+ +produce exactly the same name\ldots{} obviously if \verb+\prefix+ have +the right definition! This possibility to have a name using macro +could seem useless but it is not true. For instance, you can realize +loops\index{loop} with names as \verb+r1+, \verb+r2+, \ldots, +\verb+r+ using the code \verb+r\the\cpt+ as variable name, where +\verb+cpt+ is a counter in the \TeX{} meaning. With \LaTeX{}, the code +is more verbose with \verb+r\number\value{cpt}+ where \verb+cpt+ is +now a \LaTeX{} counter. We will see an example using this syntax in +the section~\ref{sec:Creation d'operations complexes} +page~\pageref{sec:Creation d'operations complexes}. + +\index{number!valid}In practice, what does it mean all these rules? +First, they means that a number writes in a decimal form can be +preceded by any sequence of plus or minus signs. Obviously, if there +is a odd number of minus signs, the number will be negative. Next, a +decimal number admits only one decimal separator symbol which can +be a dot or a comma, this one can be put anywhere in the +number. Finally, a number is write in basis~10. Be carefull: these +rules mean that \verb+-a+ is not valid. + +The package uses some private names and it is safe to not begin a +variable name with the character \texttt{@}. + +\section{\package{xlop} Parameters} +\label{sec:Parametres de xlop} +\index{parameter!syntax|(} +Parameter assignments are local to the macro when they are indicated +in the optional argument. To make global a parameter assignment, you +have to use the \macro{opset} macro. For example: +\begin{Verbatim}[xrightmargin=0pt] + \opset{decimalsepsymbol={,}} +\end{Verbatim} +give the comma as decimal separator symbol for the whole document, at +least, until another redefinition with \verb+\opset+. + +\subsection{Symbols} +\label{subsecSymboles} +The \parameter{afterperiodsymbol} parameter indicates the symbol that +follows a quotient in line in a division with period +search\index{division!period}. Its default value is \verb+$\ldots$+ + +The \parameter{equalsymbol} parameter indicates the symbol used for +equality. Its default value is \verb+$=$+. In fact, this parameter is +defined with: +\begin{Verbatim}[xrightmargin=0pt] + \opset{equalsymbol={$=$}} +\end{Verbatim} +that is, with braces in order to protect the equal sign. Without +theses braces, there will be a compilation error. You have to process +like that when there is an equal sign or a comma in the +value.\index{parameter!with ``='' or ``,''\quad} + +The parameter \parameter{approxsymbol} indicates the symbol used for +approximations. Its default value is \verb+$\approx$+. + +The parameter \parameter{decimalsepsymbol} indicates the symbol used +for the decimal separator. Its default value is a dot. + +Parameters \parameter{addsymbol}, \parameter{subsymbol}, +\parameter{mulsymbol}, and \parameter{divsymbol} indicate the symbols +used for the four arithmetic operations. The default value are +\verb!$+$!, \verb!$-$!, \verb!$\times$! et \verb!$\div$! respectively. + +\subsection{General Displaying} +\label{subsec:Presentation generale} +The \parameter{voperation} parameter indicates the way a dispayed +operation is put with respect to the baseline. The possible values are +\verb+top+, \verb+center+, and \verb+bottom+, the latter one is the +default value. +\begin{SideBySideExample} + top\quad + \opadd[voperation=top]{45}{172}\par + center\quad + \opadd[voperation=center]{45}{172}\par + bottom\quad + \opadd[voperation=bottom]{45}{172} +\end{SideBySideExample} + +The \parameter{voperator} parameter indicates how the operator symbol +is put with repect to operands. The possible values are \verb+top+, +\verb+center+ (default value), and \verb+bottom+. +\begin{SideBySideExample} + top\quad + \opadd[voperator=top]{45}{172}\par + center\quad + \opadd[voperator=center]{45}{172}\par + bottom\quad + \opadd[voperator=bottom]{45}{172} +\end{SideBySideExample} + +The \parameter{deletezero} parameter indicates if some numbers in +operation should be displayed with or whithout non-significant +zeros. Exact rôle of this parameter depends of the actual +operation. We will see that when we will study the different +operations. + +The \parameter{style} parameter indicates the way an operation is +displayed: display with \verb+display+ value (default value) or inline +with \verb+text+ value. We will see when we will study division +because there is many possibilities with this operation. +\begin{SideBySideExample} + \opadd[style=text]{45}{172} +\end{SideBySideExample} +In inline operations, \package{xlop} takes care to not typeset the +formula in mathematic mode in a direct way. This allow to specify what +you want as in the next example, and it is also for that that you have +to specify the classical values of symbols between mathematic +delimiters. +\begin{SideBySideExample} + \opadd[addsymbol=plus, + equalsymbol=equal, + style=text]{42}{172} +\end{SideBySideExample} +Meanwhile, \package{xlop} introduces exactly the same penalities and +the same spaces as for a mathematic formula. + +The \parameter{parenthesisnegative} parameter indicates how to typeset +negative numbers in inline operations. The possible values are: +\begin{itemize} +\item \texttt{none} which typesets negative numbers without + parenthesis; +\item \texttt{all} which typesets negative numbers with parenthesis; +\item \texttt{last} which typesets negative numbers with parenthesis + but the first one. +\end{itemize} +\begin{SideBySideExample} + \opadd[style=text, + parenthesisnegative=none] + {-12}{-23}\par + \opadd[style=text, + parenthesisnegative=all] + {-12}{-23}\par + \opadd[style=text, + parenthesisnegative=last] + {-12}{-23} +\end{SideBySideExample} + +\subsection{Dimensions} +\label{subsec:Dimensions} +In displayed operations, figures are put in fixed size boxes. The +width is given by the \parameter{lineheight} parameter and the height +is given by the \parameter{lineheight} parameter. The default value of +\texttt{lineheight} is \verb+\baselineskip+ that is, interline space +in operation is the same (by default) as in the normal text. The +default value for \texttt{columnwidth} is \texttt{2ex} because the +``normal'' width of figures would give bad results. +\begin{SideBySideExample} + \opadd[columnwidth=0.5em] + {45.89}{127.5} +\end{SideBySideExample} +One reason for this bad result is that the decimal separator is put in +a box which width is controlled by the \parameter{decimalsepwidth} +parameter and the default value of this parameter is null. You can +improve this presentation giving a ``normal'' width to the dot. +\begin{SideBySideExample} + \opadd[columnwidth=0.5em, + decimalsepwidth=0.27778em] + {45.89}{127.5} +\end{SideBySideExample} +It is better but give a positive width to the box that contain the +decimal separator is risked. It will be more difficult to place +extern object and it is counter against the idea to have a fixed +grid. You should avoid this in normal time. + +The \parameter{columnwidth} and \parameter{lineheight} parameters +correspond to the only dimensions that \package{xlop} provides as +public one, that is, +\verb+\opcolumnwidth+\index{opcolumnwidth@\texttt{$\backslash$opcolumnwidth}} +and +\verb+\oplineheight+\index{oplineheight@\texttt{$\backslash$oplineheight}} +respectively. It is dangerous to directly modify these dimensions +since a modification in a ``normal'' way doesn't only change the +dimension value. Package \package{xlop} make these dimensions public +only for reading, not for writting. + +The two next parameters allow to specify width of horizontal and +vertical rules stroked by \package{xlop}. We have +\parameter{hrulewidth} and \parameter{vrulewidth} parameters. The +default values are both \texttt{0.4pt}. + +These rules are typeset with no change on grid. That is, with no space +added. Therefore, with great values for thickness, the rules could +run over numbers. +\begin{SideBySideExample} + \opadd[hrulewidth=8pt]{42}{172} +\end{SideBySideExample} + +There is also a paramater which allows to control the horizontal shift +of decimal separator. It is the \parameter{decimalsepoffset} paramater +with a default value of~\texttt{-0.35}. This value indicates a length +with the unit \verb+\opcolumnwidth+. We will see an example at +section~\ref{sec:Division} page~\pageref{sec:Division}. + +\subsection{Figure's Styles} +\label{subsec:Styles des chiffres} +The \package{xlop} package provides five types of numbers and +associates five style paramaters: +\begin{itemize} +\item operands with \parameter{operandstyle}; +\item result with \parameter{resultstyle}; +\item remainders with \parameter{remainderstyle}; +\item intermediary numbers with \parameter{intermediarystyle}; +\item carries with \parameter{carrystyle}. +\end{itemize} +\begin{SideBySideExample} + \opadd[operandstyle=\blue, + resultstyle=\red, + carrystyle=\scriptsize\green] + {45.89}{127.5} +\end{SideBySideExample} +Keep in mind that, in this manual, we use +\package{pstricks}\index{pstricks} package. + +\index{parameter!index|(}% +In fact, the management of these styles is even more powerfull since +you can distingish different number of a same class. In one operation, +you have several operands, and, possibly several remainders and +several intermediary numbers. You can access to the style of these +numbers adding an index to the matching style. +\begin{SideBySideExample} + \opadd[operandstyle=\blue, + operandstyle.1=\lightgray, + resultstyle=\red, + carrystyle=\scriptsize\green] + {45.89}{127.5} +\end{SideBySideExample} +In this example, we indicate that the first operand must be typesetted +with the \verb+\lightgray+ style. We don't indicate anything for the +second operand, so it takes the basic style for its class. (Then with +\verb+\blue+ style.) + +This mechanism is even more powerfull since you can write two level +index for operands, carries, and intermediary numbers (one level for +result and carry) in order to access to each style figure of these +numbers. To simplify index, a positive index indicates the rank of a +figure in the integer part (right to left order, index~1 is for the +unit figure) and a negative index indicates the rank of a figure in +the decimal part (left to right order, $-1$ is for the tenth figure). +\begin{SideBySideExample} + \opadd[operandstyle.1.1=\white, + operandstyle.1.-2=\white, + operandstyle.2.3=\white, + resultstyle.2=\white, + deletezero=false] + {045.89}{127.50} +\end{SideBySideExample} +You can also use a macro with one parameter as a style. +\begin{SideBySideExample} + \newcommand\hole[1]{$\bullet$} + \opadd[operandstyle.1.1=\hole, + operandstyle.1.-2=\hole, + operandstyle.2.3=\hole, + resultstyle.2=\hole] + {45.89}{127.5} +\end{SideBySideExample} +\index{operation!with hole}% +When the style is a macro with argument, this one is the figure. Here +is a more complicated example using \package{pst-node} package of the +\package{pstricks} bundle: +\begin{SideBySideExample} + \newcommand\OPoval[3]{% + \dimen1=#2\opcolumnwidth + \ovalnode{#1} + {\kern\dimen1 #3\kern\dimen1}} + \opadd[voperation=top, + operandstyle.1.1=\OPoval{A}{0}, + operandstyle.2.2=\OPoval{C}{0.8}] + {45}{172}\qquad + \begin{minipage}[t]{2cm} + \pnode(0,0.2em){B}\ figure + \ncarc{->}{A}{B}\par + \pnode(0,0.2em){D}\ number + \ncarc{<-}{D}{C} + \end{minipage} +\end{SideBySideExample} +As for figures, the decimal separator take account to number style. To +access individually to the decimal separator style, you have to use +\texttt{d} index, numeric indexes are for figures. +\begin{SideBySideExample} + \newcommand\hole[1]{\texttt{\_}} + \opmul[intermediarystyle=\hole, + resultstyle=\hole, + resultstyle.d=\white]{2.46}{35.7} +\end{SideBySideExample} +\index{parameter!index|)}% +\index{parameter!syntax|)} + +\chapter{Arithmetic Operations} +\label{chap:Opérations arithmétiques} +\section{Addition} +\label{sec:Addition} +Addition is deal by the \macro{opadd} macro. When it is in display +mode, it display only nonnegative numbers. Then, it displays a +substraction when one of the operands is nonpositive.% +\index{number!nonpositive in displayed operation} +\begin{SideBySideExample} + \opadd{-245}{72} +\end{SideBySideExample} +In a general manner, the principle is to display the operation that +allows to find the result as you make it ``by hand''. On the contrary, +the inline mode shows always an addition since we can now write +nonpositive numbers. +\begin{SideBySideExample} + \opadd[style=text]{-245}{72} +\end{SideBySideExample} +In addition to the general parameters discussed in the +section~\ref{sec:Parametres de xlop}, the macro \verb+\opadd+ uses +parameters \texttt{carryadd}, \texttt{lastcarry}, and +\texttt{deletezero}. + +The \parameter{carryadd} parameter is a boolean +parameter\index{parameter!boolean}, that is, it accepts only the +values \texttt{true} and \texttt{false}. By habit, when you don't +specify the value and the equal sign, that is like assignment +\texttt{=true}. This parameter indicates if the carries must be showed +or not. Its default value is \texttt{true}. + +The \parameter{lastcarry} parameter is also a boolean parameter. It +indicates if a carry without matching digit for the two operands must +be showed or not. Its default value is \texttt{false}. Take care to +the exact rôle of this parameter. For instance, if the second operand +in the following example is~15307, the last carry would be showed for +any value of the \texttt{lastcarry} parameter since there is a +matching digit in the second operand. +\begin{SideBySideExample} + \opadd{4825}{5307} +\end{SideBySideExample} +\begin{SideBySideExample} + \opadd[carryadd=false]{4825}{5307} +\end{SideBySideExample} +\begin{SideBySideExample} + \opadd[lastcarry]{4825}{5307} +\end{SideBySideExample} + +The \parameter{deletezero} parameter is also a boolean parameter. It +indicates if non-significant zeros must be deleted or not. Its default +value is \texttt{true}. When this parameter is \texttt{false}, the +operands and the result have the same number of digits. For that, +\package{xlop} package adds non-significant zeros. Also, the +non-significant zeros of operands are not removed. +\begin{SideBySideExample} + \opadd{012.3427}{5.2773}\par + \opadd[deletezero=false] + {012.3427}{5.2773} +\end{SideBySideExample} + +This parameter has exactly the same rôle for inline mode than for +displayed mode. +\begin{SideBySideExample} + \opadd[style=text]{02.8}{1.2}\par + \opadd[style=text, + deletezero=false]{02.8}{1.2}\par +\end{SideBySideExample} + +\section{Substraction} +\label{sec:soustraction} +Substraction is made by \macro{opsub} macro. In displayed mode, the +substraction shows only nonnegative numbers. For that, it shows an +addition when one operand is nonpositive. +\begin{SideBySideExample} + \opsub{-245}{72} +\end{SideBySideExample} +In a general way, the principle is to display the operation which +allow to find the result as you make it ``by hand''. On the contrary, +inline mode shows always a substraction since you can now write +nonpositive numbers. +\begin{SideBySideExample} + \opsub[style=text]{-245}{72} +\end{SideBySideExample} +This principle apply also when the first operand is less than the +second one (positive case). In this case, we have an operand +inversion. +\begin{SideBySideExample} + \opsub{1.2}{2.45} +\end{SideBySideExample} +Of course, inline operation gives an exact result. +\begin{SideBySideExample} + \opsub[style=text]{1.2}{2.45} +\end{SideBySideExample} + +In addition to general parameters we have seen at +section~\ref{sec:Parametres de xlop}, \verb+\opsub+ takes account of +\texttt{carrysub}, \texttt{lastcarry}, \texttt{offsetcarry}, +\texttt{deletezero}, and \texttt{behaviorsub} parameters. + +The \parameter{carrysub} parameter is a boolean one which indicates if +carries must be present or not. Its default value is \texttt{false}. +(Remember that the default value of \texttt{carryadd} parameter is +\texttt{true}.) +\begin{SideBySideExample} + \opsub[carrysub]{1234}{567} +\end{SideBySideExample} + +In the last example, you can see that there is no carry above the last +digit of 1234. This is quite common (at least in France). If you want +display this last carry, you have to use the \parameter{lastcarry} +parameter. This parameter does not have the same behavior in +substraction and in addition since here, the last carry is not +displayed when the second operand does not have correspondent +digit. (For addition, last carry is not displayed when \emph{all} the +operands do not have correspondent digit.) +\begin{SideBySideExample} + \opsub[carrysub,lastcarry]{1234}{567} +\end{SideBySideExample} +Note that, in this case, it is better to set the +\parameter{deletezero} parameter to \texttt{false} in order to have a +nicer result. +\begin{SideBySideExample} + \opsub[carrysub, + lastcarry, + deletezero=false]{1234}{567} +\end{SideBySideExample} + +Perhaps it seems to you that showing carries for substraction is a bit +more dense. You can enlarge the figure box with the +\parameter{opcolumnwidth} parameter. You can also indicate the carry +horizontal shift using the \parameter{offsetcarry} parameter. Its +default value is \texttt{-0.35}. +\begin{SideBySideExample} + \opsub[carrysub, + lastcarry, + deletezero=false]{12.34}{5.67} + + \bigskip + \opsub[carrysub, + lastcarry, + columnwidth=2.5ex, + offsetcarry=-0.4, + decimalsepoffset=-3pt, + deletezero=false]{12.34}{5.67} +\end{SideBySideExample} + +It is possible that a substraction with two positive numbers and with +the first one less than the second one signs an user error. In this +case, and only in this case, the \parameter{behaviorsub} parameter +allows a call to order. The three possible values are: +\begin{itemize} +\item \texttt{silent} which is the default value and which gives the + result; +\item \texttt{warning} which gives also the result but shows the + warning message: +\begin{Verbatim}[xrightmargin=0pt,frame=none] + xlop warning. Substraction with first operand less than second one + See documentation for further information. +\end{Verbatim} +\item \texttt{error} which shows the error message: +\begin{Verbatim}[xrightmargin=0pt,frame=none] + xlop error. See documentation for further information. + Type H for immediate help. + ! Substraction with first operand less than second one. +\end{Verbatim} + and the operation is not performed. +\end{itemize} + +\section{Multiplication} +\label{sec:Multiplication} +The multiplication is under the control of the \macro{opmul} macro. + +The parameters we will see below are \texttt{hfactor}, +\texttt{displayintermediary}, \texttt{shiftintermediarysymbol}, and +\texttt{deletezero}. We studied the other parameters in +section~\ref{sec:Parametres de xlop}. + +The \parameter{shiftintermediarysymbol} parameter indicates what is +the symbol used for showing the shifting of intermediary numbers +(default value is \verb+$\cdot$+). The +\parameter{displayshiftintermediary} parameter can take value +\texttt{shift} (default value) which shows this symbol only for +shifting greater than one level, value \texttt{all} which shows this +symbol for all the shiftings, and the value \texttt{none} which means +that this symbol will be never showed. +\begin{CenterExample}[xrightmargin=0pt] + \opmul[displayshiftintermediary=shift]{453}{1001205}\qquad + \opmul[displayshiftintermediary=all]{453}{1001205}\qquad + \opmul[displayshiftintermediary=none]{453}{1001205} +\end{CenterExample} + +In fact, null intermediary numbers are not display because of the +default value \texttt{none} of the \parameter{displayintermediary} +parameter. The value \texttt{all} shows all the intermediary numbers, +even null intermediary numbers. +\begin{SideBySideExample} + \opmul[displayintermediary=all] + {453}{1001205} +\end{SideBySideExample} +Note that null intermediary numbers are displayed with the same width +than the first factor width. + +The \parameter{displayintermediary} parameter accepts the value +\texttt{nonzero} which means the same than the \texttt{none} value +except when second factor has only one digit. +\begin{CenterExample}[xrightmargin=0pt] + \opmul{3.14159}{4}\qquad + \opmul[displayintermediary=nonzero]{3.14159}{4} +\end{CenterExample} + +The \parameter{hfactor} parameter indicates how align operands. The +default value, \texttt{right}, gives a raggedleft alignment. The +\texttt{decimal} value gives an alignment on dot. +\begin{CenterExample}[xrightmargin=0pt] + \opmul{3.1416}{12.8}\qquad\opmul[hfactor=decimal]{3.1416}{12.8} +\end{CenterExample} + +For displayed multiplication, the \parameter{deletezero} parameter is +only for operands. The result keeps its non-significant zeros since +there are necessary in order to make a correct dot shifting when we +work ``by hand''. +\begin{CenterExample}[xrightmargin=0pt] + \opmul[deletezero=false]{01.44}{25}\qquad + \opmul{01.44}{25} +\end{CenterExample} +In the other hand, this parameter has its usual behaviour in inline +multiplication. +\begin{CenterExample}[xrightmargin=0pt] + \opmul[deletezero=false,style=text]{01.44}{25}\qquad + \opmul[style=text]{01.44}{25} +\end{CenterExample} + +\section{Division} +\label{sec:Division} +The \package{xlop} package deals with ``normal'' division via +\macro{opdiv} macro and with euclidean division via \macro{opidiv} +macro. Division is a very complex operation so it is not strange that +there are many parameters to control it. + +Pay attention that the \package{xlop} package v. 0.23 is unable to +deal with ``english'' division. In this package version, the division +is the ``french'' one, which is more or less used as it in some other +countries. The \package{xlop} package v. 0.3 will allow ``enlish'' +division (and many more feautures). + +\subsection{End Control} +\label{subsec:Controle de l'arret} +In the following text, term \emph{step} means the set of process which +allow to get one digit for the quotient. This number of steps is (not +only) under the control of \parameter{maxdivstep}, +\parameter{safedivstep}, and \parameter{period} parameters. It is only +partially true because a classical division will stop automatically +when a remainder will be zero, whatever the values of these three +parameters and a euclidean division will stop with an integer quotient +without attention for these three parameters. +\begin{SideBySideExample} + \opdiv{25}{7} +\end{SideBySideExample} +\begin{SideBySideExample} + \opidiv{25}{7} +\end{SideBySideExample} +The first example stops because of the value of \parameter{maxdivstep} +which is 10 by default. Pay attention that the maximum step number +could cause strange result when it is too small. +\begin{SideBySideExample} + \opdiv[maxdivstep=2]{1248}{3} +\end{SideBySideExample} +Clearly, the last result is false. In the other hand, \package{xlop} +package did what we have ask, that is, obtain two digits (maximum) for +the quotient. + +The inline mode differ with zero remainder or not and with the type of +division (classical or euclidean). +\begin{SideBySideExample} + \opdiv[style=text]{3.14}{2}\par + \opdiv[style=text]{3.14}{3}\par + \opidiv[style=text]{314}{2}\par + \opidiv[style=text]{314}{3} +\end{SideBySideExample} +Note the use of \parameter{equalsymbol} or \parameter{approxsymbol} +parameter according to the case. Note also that \package{xlop} +displays results with floor, not with round. We will see how obtain a +round in section~\ref{sec:Operations evoluees}. + +For inline mode of \verb+\opdiv+, \package{xlop} take account of +\parameter{maxdivstep}. It means that we can obtain results very false +with too small values of this parametrer and, unlike with display mode +division, inline mode don't allow to understand what is wrong. +\begin{SideBySideExample} + \opdiv[maxdivstep=2,style=text] + {1248}{3} +\end{SideBySideExample} +In addition, if the last remainder is zero, we obtain a must: +\begin{SideBySideExample} + \opdiv[maxdivstep=1,style=text] + {1208}{3} +\end{SideBySideExample} +because there is no approximation at all! + +A classical division can stop with period detection. For that, you +have just to give the value \texttt{true} for the \parameter{period} +parameter\index{division!period}. +\begin{SideBySideExample} + \opdiv[period]{100}{3} +\end{SideBySideExample} + +To avoid comparizons between each remainder with all previous +remainder, \package{xlop} calculates immediatly the period +length. That allows to process only one comparizon for each step, then +to have a much more efficient process.\footnote{Thanks to Olivier + Viennet about mathematic precisions that allows to implement these + calculations.} Unfortunately, these calculations are made with +numbers that are directly accesible to \TeX{}. As consequence, you +can't use operand with absolute value greater than +$\left\lfloor\frac{2^{31}-1}{10}\right\rfloor = 214748364$. + +In order to avoid too long calculations, \package{xlop} don't process +beyond the value of \parameter{safedivstep} parameter in division with +period. Its default value is~50. However, \package{xlop} package show +this problem. For example, if you ask for such a division with the +code: +\begin{Verbatim}[xrightmargin=0pt,frame=none] + \opdiv[period]{1}{289} +\end{Verbatim} +you obtain the warning message: +\begin{Verbatim}[xrightmargin=0pt,frame=none] + xlop warning. Period of division is too big (272 > safedivstep). + Division will stop before reach it. + See documentation for further information. +\end{Verbatim} +which indicates that this division period is~272 and that it can be +achieved because of the \texttt{safedivstep} value. + +The inline mode for division with period have some particularities. +\begin{SideBySideExample} + \opdiv[period,style=text]{150}{7} +\end{SideBySideExample} +We obtain an equality rather than an approximation, there is a rule +under the period, and there is ellipsis after the period. All these +components can be configured. The equality symbol is given +by the \parameter{equalsymbol} parameter (default value is +\verb+{$=$}+). The rule thickness is given by +the \parameter{hrulewidth} parameter (default value is +\texttt{0.4pt}). The vertical offset of this rule is given +by \parameter{vruleperiod} parameter (default value is \texttt{-0.2}) +which indicates a vertical offset taking \verb+\oplineheight+ as +unit. The ellipsis are given by the +parameter \parameter{afterperiodsymbol} (default value +\verb+$\ldots$+). +\begin{SideBySideExample} + \opdiv[period,style=text, + equalsymbol=$\approx$, + hrulewidth=0.2pt, + vruleperiod=0.7, + afterperiodsymbol=] + {150}{7} +\end{SideBySideExample} + +\subsection{Other Features} +\label{subsec:Elements supplementaires} +Displayed divisions can include successive substractions which allow +remainder calculations. For \package{xlop}, the numbers which are +substracted are intermediary numbers, so the different ways to +represent substractions use \parameter{displayintermediary} parameter +see for multiplication. The default value, valeur \texttt{none}, don't +display any substraction; the value \texttt{all} displays all the +substractions, and the value \texttt{nonzero} displays substractions +with non-zero numbers +\begin{CenterExample}[xrightmargin=0pt] + \opdiv[displayintermediary=none,voperation=top] + {251}{25}\quad + \opdiv[displayintermediary=nonzero,voperation=top] + {251}{25}\quad + \opdiv[displayintermediary=all,voperation=top] + {251}{25} +\end{CenterExample} + +When we write a display division, we can draw a ``bridge'' over the +part of dividend which is taken in count for the first step of +calculation. The \package{xlop} package allow to draw this symbol +thanks to the boolean parameter \parameter{dividendbridge} (default +value is \texttt{false}). +\begin{SideBySideExample} + \opdiv[dividendbridge]{1254}{30} +\end{SideBySideExample} + +\subsection{Non Integer Numbers and Negative Numbers} +\label{subsec:Nombres non entiers et negatifs} +The \parameter{shiftdecimalsep} parameter governs non integer operands +aspect/ Its default value is \texttt{both} which indicates that +decimal separator is shifted in order to obtain integer divisor and +integer dividend. The value \texttt{divisor} indicates that there is +the shifting that allows an integer divisor. The value \texttt{none} +indicates that there isn't any shifting. +\begin{CenterExample}[xrightmargin=0pt] + \opdiv[shiftdecimalsep=both]{3.456}{25.6}\quad + \opdiv[shiftdecimalsep=divisor]{3.456}{25.6}\quad + \opdiv[shiftdecimalsep=none]{3.456}{25.6} +\end{CenterExample} + +Parameter \parameter{strikedecimalsepsymbol} gives the symbol used +to show the old place of decimal separator when this one is +shifted. The default value is empty, that is, there isn't any +symbol. This explain why you don't see anything on previous examples. +\begin{CenterExample}[xrightmargin=0pt] + \opset{strikedecimalsepsymbol={\rlap{,}\rule[-1pt]{3pt}{0.4pt}}} + \opdiv[shiftdecimalsep=both]{3.456}{25.6}\quad + \opdiv[shiftdecimalsep=divisor]{3.456}{25.6}\quad + \opdiv[shiftdecimalsep=none]{3.456}{25.6} +\end{CenterExample} + +When there is a non empty symbol for the striked decimal separator, it +is possible to have non-significant zeros in operands. +\begin{SideBySideExample} + \opdiv[shiftdecimalsep=divisor, + strikedecimalsepsymbol=% + \hspace{-3pt}\tiny$\times$] + {0.03456}{2.56} +\end{SideBySideExample} + +We have already seen that \macro{opidiv} macro gives integer +quotient. This is true even with non integer operands. It is somewhere +strange to perform an euclidian division with non integer operands. The +\macro{opidiv} macro will be strict about the +presentation. Parameters \parameter{maxdivstep}, \parameter{safedivstep}, +and \parameter{period} haven't any effect, as +for \parameter{shiftdecimalsep} parameter since operands are changed +to integer ones. +\begin{SideBySideExample} + \opidiv[strikedecimalsepsymbol=% + \hspace{-3pt}\tiny$\times$] + {34.57}{7} +\end{SideBySideExample} + +When operands are negative, the inline \macro{opidiv} numbers is +different from the displayed \macro{opidiv} ones. Remainder will be +between zero (include) and absolute value of divisor (exclude). +\begin{SideBySideExample} + \opdiv[style=text]{124}{7}\par + \opidiv[style=text]{124}{7}\par + \opidiv[style=text]{124}{-7}\par + \opidiv[style=text]{-124}{7}\par + \opidiv[style=text]{-124}{-7} +\end{SideBySideExample} + +This condition for remainder is valid even with non integer divisor. +\begin{SideBySideExample} + \opidiv[style=text]{1.24}{0.7}\par + \opidiv[style=text]{1.24}{-0.7}\par + \opidiv[style=text]{-1.24}{0.7}\par + \opidiv[style=text]{-1.24}{-0.7} +\end{SideBySideExample} + +\chapter{Other Commands} +\label{chap:Autres commandes} +\section{Starred Macros} +\label{sec:Macros etoilees} +The five macros seen in previous chapter have a starred version. These +starred macros perform the calculation and don't display +anything. Result is record in a variable given as argument. + +Since these commands don't display anything, parameters don't make +sens and aren't allowed for \macro{opadd*}, \macro{opsub*}, +\macro{opmul*}, and \macro{opidiv*}. In the other hand, +parameters \parameter{maxdivestep}, \parameter{safedivstep}, +and \parameter{period} influence calculations, then \macro{opdiv*} +macro accepts an optional argument to take account of them. +\begin{SideBySideExample} + \opmul*{2}{2}{a}% + \opmul*{a}{a}{a}\opmul*{a}{a}{a}% + \opadd[style=text]{a}{1} +\end{SideBySideExample} +For macros \macro{opdiv} and \macro{opidiv}, there are two extra +arguments to record quotient and final remainder. +\begin{SideBySideExample} + \opdiv*[maxdivstep=1]{-88}{16}{q}{r}% + \opmul*{q}{16}{bq}% + \opmul[style=text]{16}{q}\par + \opadd[style=text]{bq}{r} +\end{SideBySideExample} + +\section{Input-Output} +\label{sec:Entree-sorties} +The \macro{opcopy} macro copies its first argument into its second +one. Then, the first argument is a number write in decimal form or +\emph{via} a variable, whereas the second one is a variable name. + +The \macro{opprint} macro displays its argument. The following example +uses the counter \macro{time} which indicates numbers of minutes since +midnight. +\begin{SideBySideExample} + \opidiv*{\the\time}{60}{h}{m}% + It is \opprint{h}~hours + \opprint{m}~minutes +\end{SideBySideExample} +We will see at section~\ref{sec:Comparaisons} how to improve this +example with tests. + +The \macro{opdisplay} macro also displays a number but here, each +figure is in a box. The width of this box is given +by \parameter{columnwidth} and the height of this box is given +by \parameter{lineheight}. Style is specified by the first +argument. This macro accepts an optional argument in order to give a +specific style for individual figures. +\begin{SideBySideExample} + \opdisplay[resultstyle.1=\bfseries, + resultstyle.-2=\bfseries] + {resultstyle}{129.192} +\end{SideBySideExample} +Macros \macro{oplput} and \macro{oprput} allow to put anything +anywhere. The syntax of both of them is different from the other ones +of \package{xlop} since the place is indicated with coordinates +between parenthesis. The coordinates use \macro{opcolumnwidth} and +\macro{oplineheight} as units. Then user is able to build his own +``operations''. +\begin{SideBySideExample} + \psset{xunit=\opcolumnwidth, + yunit=\oplineheight}% + \psgrid[subgriddiv=1,gridlabels=7pt, + griddots=5](0,1)(10,-2) + \oplput(2,0){Hello} + \oprput(8,-1){world!} + $\bullet$ +\end{SideBySideExample} +On example above, note that these macros don't move the reference +point. As a precaution, they kill the trailing space and then, there +is no need to protect the end of line with a \verb+%+. + +Macros \macro{ophline} and \macro{opvline} complete the previous ones +to give all the tools the user needs to build its own operations. +\macro{ophline} allows to draw a horizontal rule; its length is given +by the parameter after coordinates. \macro{opvline} does the same for +vertical rules. Remember that parameters \parameter{hrulewidth} +and \parameter{vrulewidth} indicate the thickness of these rules. +\begin{CenterExample}[xrightmargin=0pt] + \par\vspace{2\oplineheight} + \oplput(1,2){O}\oplput(2,2){N}\oplput(3,2){E} + \oplput(0,1.5){$+$} + \oplput(1,1){O}\oplput(2,1){N}\oplput(3,1){E} + \ophline(0,0.8){4} + \oplput(1,0){T}\oplput(2,0){W}\oplput(3,0){O} +\end{CenterExample} + +Macro \macro{opexport}\refstepcounter{stuff}\label{macro-opexport} +allow to export a number in a macro. It's an extra to version~0.23 +which is very usefull to exchange datas between \package{xlop} and the +outside world. The first argument is a number in the \package{xlop} +sense, that is, either a number write with figures, or a variable +name. The number is translated in a form directly acceptable for +\TeX{} and hold in the second argument which should be a macro +name. However, note that decimal separator will be the one specified +by \parameter{decimalsepsymbol} (without its possible braces). +\begin{SideBySideExample} + \opmul*{5}{3.141592654}{F} + \opexport{F}{\fivepi} + \texttt{\meaning\fivepi} +\end{SideBySideExample} +We can use this macro to typeset numbers calculated by \package{xlop} +in an array with a decimal alignment, or to initialize a counter or a +length (don't forget the unit in the last case). + +\section{Figures of Numbers} +\label{sec:Chiffres d'un nombre} +Macros \macro{opwidth}, \macro{opintegerwidth}, and +\macro{opdecimalwidth} indicate number of digits of the whole number, +of its integer part, of its decimal part respectively. The first +argument is the examined number and the second one indicates the +variable where result will be record. +\begin{SideBySideExample} + \opcopy{123456.1234}{a}% + \opwidth{a}{na}% + \opintegerwidth{a}{ia}% + \opdecimalwidth{a}{da}% + \opprint{a} is written with + \opprint{na} figures (\opprint{ia} in + the integer part and \opprint{da} in + the decimal part). +\end{SideBySideExample} + +Macro \macro{opunzero} delete all the non-significant +zeros\index{non-significant zero} of the number passed as argument. +\begin{SideBySideExample} + \opcopy{00150.00250}{a}% + Before : \opprint{a}\par + \opunzero{a}% + After : \opprint{a} +\end{SideBySideExample} + +Macros \macro{integer} and \macro{opdecimal} give the integer part and +the decimal part of a number respectively. +\index{number!integer part}\index{integer part}% +\index{number!decimal part}\index{decimal part}% +First argument is the number to process, and the second one is the +variable name which hold the result. +\begin{SideBySideExample} + \opcopy{-37.69911}{a}% + \opinteger{a}{ia}% + \opdecimal{a}{da}% + Integer part: \opprint{ia}\par + Decimal part: \opprint{da} +\end{SideBySideExample} + +Six macros allow to write or read a figure of a number. You can read +or read a figure according to its place in the whole number, or in the +integer part, or in the decimal part. Figures for whole number and for +decimal part are numbered from right to left, figures for integer part +are numbered from left to right. For instance, with the number +1234.56789, the second figure is 8, the second figure of the integer +part is 3, and the second figure of the decimal part is 6. It is now +easy to guess the rôle of the six next macros: +\begin{itemize} +\item \parameter{opgetdigit} ; +\item \parameter{opsetdigit} ; +\item \parameter{opgetintegerdigit} ; +\item \parameter{opsetintegerdigit} ; +\item \parameter{opgetdecimaldigit} ; +\item \parameter{opsetdecimaldigit} ; +\end{itemize} +Syntax is the same for these macros. The first argument is the +processed number (reading or writting), the second one is the index of +te figure, and the third one is the variable name which hold the +result (figure read or changed number). If index is out of the range, +the reading macros give \texttt{0} as result and writing macros +extend the number in order to reach this index (for that, zero will be +created in new slots). + +\section{Comparisons} +\label{sec:Comparaisons} +When you want complex macros, often you need to realize tests. For +that, \package{xlop} gives the macro \macro{opcmp}. The two +arguments are numbers and this macro setup the tests \macro{ifopgt}, +\macro{ifopge}, \macro{ifople}, \macro{ifoplt}, \macro{ifopeq}, and +\macro{ifopneq} to indicate that first operand is greater, greater or +equal, less or equal, less, equal, or different to the second operand +respectively. + +For technical reasons, \package{xlop} give global definitions for the +six tests above. Then, they are not protected by groups. Since these +tests are used by many \package{xlop} macros, you must \emph{always} +use tests \verb+\ifop...+ immediately after \macro{opcmp}, or, at +least, before any use of a \package{xlop} macro. Otherwise, there will +be bugs hard to fix! + +Let's resume the hour display macro see at +section~\ref{sec:Entree-sorties}. But now, we check if argument is +between 0 (include) and 1440 (exclude), then we process tests in order +to know if ``hour'' is plural or not, as for ``minute''. + +\begin{CenterExample}[xrightmargin=0pt] + \newcommand\hour[1]{% + \opcmp{#1}{0}\ifopge + \opcmp{#1}{1440}\ifoplt + \opidiv*{#1}{60}{h}{m}% + \opprint{h} hour% + \opcmp{h}{1}\ifopgt + s% + \fi + \opcmp{m}{0}\ifopneq + \space\opprint{m} minute% + \opcmp{m}{1}\ifopgt + s% + \fi + \fi + \fi\fi + } + \hour{60} -- \hour{1080} -- \hour{1081} -- \hour{1082} +\end{CenterExample} + +\section{Advanced Operations} +\label{sec:Operations evoluees} +The macros left to be examined are either internal macros and which it +will be a shame to keep private , or macro asked for users. + +Internal macros are \macro{opgcd}\index{gcd} which gives gcd of two +numbers and macro \macro{opdivperiod}\index{division!period} which +gives the period length of quotient of two numbers. For efficiency +reason, these macros don't use \package{xlop} number, they rather use +numbers directly understand by \TeX{}. There are two consequences: the +numbers can't be greater than \texttt{2147483647} for \macro{opgcd}; +it can't be greater than \texttt{214748364} for +\macro{opdivperiod}. A warning is displayed for an overflow. Result is +put in the third parameter. + +There is also some checks on the two first parameters: a gcd mustn't +have null argument; length of period can't be processed with null +quotient. Futhermore, if an argument is a non integer number, only the +integer part will be take account. +\begin{SideBySideExample} + \opcopy{5376}{a}% + \opcopy{2304}{b}% + \opgcd{a}{b}{gcd(ab)}% + $\gcd(\opprint{a},\opprint{b}) = + \opprint{gcd(ab)}$ +\end{SideBySideExample} +You can play and find long period of divisions. Without going into +mathematical details, square of prime numbers are good choices. For +instance with $257^2=66049$ you obtain: +\begin{SideBySideExample} + \opdivperiod{1}{66049}{p}% + $\frac{1}{66049}$ have a period + of length $\opprint{p}$. +\end{SideBySideExample} + +With macros \macro{opcastingoutnines}\index{casting out of nines} and +\macro{opcastingoutelevens}\index{casting out of elevens} you can +build casting out of nines and casting out of elevens. \package{xlop} +don't typeset directly these ``operations'' since they need diagonal +rules, and then, need some particular packages. In fact, macro +\macro{opcastingoutnines} calculates the sum modulo~9 of first +argument digits and put the result in second argument. Macro +\macro{opcastingoutelevens} calculates the sum modulo~11 of the even +rank digits of first argument, calculates the sum moldulo~11 of the +odd rank digits of first argument, and calculates the difference of +these two sums. +\begin{SideBySideExample} + \newcommand\castingoutnines[3]{% + \opcastingoutnines{#1}{cna}% + \opcastingoutnines{#2}{cnb}% + \opmul*{cna}{cnb}{cna*cnb} + \opcastingoutnines{cna*cnb}{cna*cnb}% + \opcastingoutnines{#3}{cn(a*b)}% + \begin{pspicture}(-3.5ex,-3.5ex)% + (3.5ex,3.5ex) + \psline(-3.5ex,-3.5ex)(3.5ex,3.5ex) + \psline(-3.5ex,3.5ex)(3.5ex,-3.5ex) + \rput(-2.75ex,0){\opprint{cna}} + \rput(2.75ex,0){\opprint{cnb}} + \rput(0,2.75ex){\opprint{cna*cnb}} + \rput(0,-2.75ex){\opprint{cn(a*b)}} + \end{pspicture} + } + \castingoutnines{157}{317}{49669} +\end{SideBySideExample} +In passing, this example shows that $157\times317\neq49669$! The right +operation is \opmul[style=text]{157}{317}. + +The two next macros are very simple. We have \macro{opneg} which +calculates the opposite of its first argument and store it in the +variable indicated by the second argument. We have also \macro{opabs} +which does the same with absolute value. + +Macro \macro{oppower} calculates integer powers of numbers. This macro +has three parameters. The third one store the first argument to the +power of the second argument. When the first argument is zero: if the +second argument is zero, result is~1; if the second argument is +positive, result is~0; if the second argument is negative, there is an +error. There isn't any limitation on first parameter. This leads to +some problems, for instance: +\begin{CenterExample}[xrightmargin=0pt] + \opcopy{0.8}{a}\opcopy{-17}{n}% + \oppower{a}{n}{r}% + $\opprint{a}^{\opprint{n}} = \opprint{r}$ +\end{CenterExample} +With $0.7$ rather than $0.8$, problem is worse: +\begin{CenterExample}[xrightmargin=0pt] + \opcopy{0.7}{a}\opcopy{-8}{n}% + \oppower{a}{n}{r}% + \opdecimalwidth{r}{dr} + $\opprint{a}^{\opprint{n}}$ has \opprint{dr} + figures after dot. +\end{CenterExample} +In fact, when exponent is negative, \emph{first} \package{xlop} +calulates inverse of the number and \emph{after that}, it calculates +the power with opposite of the exponent. In this example, if we had +left $-17$ rather than $-8$, then there will be a capacity overflow +capacity of \TeX{}. + +Three macros allow a control about precision. They allow to +approximate a number giving the rank of the approximation. There are +\macro{opfloor}, \macro{opceil}, and \macro{opround}. They need three +parameters which are (in order): start number, rank of approximation, +variable name to store the result. + +Rank is an integer value giving number of digits after decimal +separator which must be present. If this rank is negative, +approximation will be done before the decimal separator. If rank +is positive and indicates more digits than decimal part has, then +zeros will be added. If rank is negative and indicates more digits +than integer part has, then approximation will be locked in order to +give the first digit of the number at least. + +Here is a summary table which allow to understand how these macros +work. +\begin{center} + \opcopy{3838.3838}{a} + \begin{tabular}{|r|l|l|l|} + \hline + \multicolumn{4}{|c|}{\textbf{\texttt{\textbackslash + op\ldots{}\{3838.3838\}\{n\}\{r\}}}}\\\hline + \multicolumn{1}{|c|}{\textbf{\texttt{n}}} & + \multicolumn{1}{c|}{\textbf{\texttt{floor}}} & + \multicolumn{1}{c|}{\textbf{\texttt{ceil}}} & + \multicolumn{1}{c|}{\textbf{\texttt{round}}} \\\hline + \opcopy{6}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\ + \opcopy{4}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\ + \opcopy{3}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\ + \opcopy{0}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\ + \opcopy{-1}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\ + \opcopy{-2}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\ + \opcopy{-6}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\\hline + \end{tabular} + \opcopy{-3838.3838}{a} + \begin{tabular}{|r|l|l|l|} + \hline + \multicolumn{4}{|c|}{\textbf{\texttt{\textbackslash + op\ldots{}\{-3838.3838\}\{n\}\{r\}}}}\\\hline + \multicolumn{1}{|c|}{\textbf{\texttt{n}}} & + \multicolumn{1}{c|}{\textbf{\texttt{floor}}} & + \multicolumn{1}{c|}{\textbf{\texttt{ceil}}} & + \multicolumn{1}{c|}{\textbf{\texttt{round}}} \\\hline + \opcopy{6}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\ + \opcopy{4}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\ + \opcopy{3}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\ + \opcopy{0}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\ + \opcopy{-1}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\ + \opcopy{-2}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\ + \opcopy{-6}{n}$\opprint{n}$ & + \opfloor{a}{n}{r}$\opprint{r}$ & + \opceil{a}{n}{r}$\opprint{r}$ & + \opround{a}{n}{r}$\opprint{r}$ \\\hline + \end{tabular} +\end{center} + +\index{complex expression|(} +The very last macro we have to study is \macro{opexpr}. It calculates +a complex expression. This macro needs two parameters: the first one +is the expression in infix form (the natural one for human), the +second one is the variable name where the result is stored. + +Initially, expression must have been polish one (for instance, +notation used on old HP calculator, or PostScript language), but +another work with Christophe Jorssen has given the actual form for +expression in \package{xlop}, more pleasant for users. + +Formulas accept usual arithmetic operators \texttt{+}, \texttt{-}, +\texttt{*}, and \texttt{/}. They accept also \texttt{:} operator for +euclidian division, and \verb+^+ for power. The \texttt{-} operator +has both rôle of substraction and unary operator for opposite. The +\texttt{+} has also these rôles, here the unary operator do\dots{} +nothing! Operands are written in decimal form or \emph{via} variable +name. However, \macro{opexpr} introduces a restriction about variable +name since variable names must be different to function names +recognized by \macro{opexpr}. Accessible functions are: +\begin{itemize} +\item \texttt{abs(a)} ; +\item \texttt{ceil(a,i)} ; +\item \texttt{decimal(a)} ; +\item \texttt{floor(a,i)} ; +\item \texttt{gcd(a,b)} ; +\item \texttt{integer(a)} ; +\item \texttt{mod(a,b)} gives result of \texttt{a} modulo + \texttt{b} ; +\item \texttt{rest(a,b)} gives remainder of \texttt{a} divide by + \texttt{b} (difference between remainider and modulo is the same as + between non euclidian division and euclidian division); +\item \texttt{round(a,i)}. +\end{itemize} +where functions that aren't listed above ask the matching macros. +(function \texttt{xxx} calls macro \verb+\opxxx+) For functions +\texttt{ceil}, \texttt{floor}, and \texttt{round}, the number +\texttt{i} indicates rank for approximation. + +Macro \macro{opexpr} accept optional argument since it can realize +division which can be controlled +by \parameter{maxdivstep},\parameter{safedivstep}, +and \parameter{period} parameters. Our first example is quite basic: +\begin{CenterExample}[xrightmargin=0pt] + \opexpr{3--gcd(15*17,25*27)*2}{r}% + $3--\gcd(15\times17,25\times27)\times2 = \opprint{r}$ +\end{CenterExample} + +Here is another example that shows that datas can come from a macro: +\begin{CenterExample}[xrightmargin=0pt] + \newcommand\try{2}% + \opexpr{\try+1/ + (\try+1/ + (\try+1/ + (\try+1/ + (\try+1/ + (\try)))))}{r} + Continued fraction of base $u_n=2$ equal \opprint{r} at rank~5. +\end{CenterExample} +\index{complex expression|)} + +\appendix +\chapter{Short Summary} +\label{chap:Aide-mémoire} +\section{Compilation times} +\label{sec:Temps de compilation} +Compilation times was measured on a computer with +processor Pentium II 600\,MHz, RAM 256\,MB, on linux system (Debian +woody).\footnote{In fact, these measures was done in 2004, when the + 0.2 version was released. Author is somewhere lasy and he doesn't + measure with his new computer (more efficient)!}. The principle is +to do a minimal file \texttt{.tex}. The general canvas is: +\begin{verbatim} + \input xlop + \count255=0 + \loop + \ifnum\count255<1000 + + \advance\count255 by1 + \repeat + \bye +\end{verbatim} +Compilation time with \verb++ empty was substract +from the others test. Only the user time was take account. Results are +given in millisecond and should be read with great precautions. + +\index{compilation time|(}\index{time (calculation)|(}% +Next table gives operation times in milliseconds. Operands used had +decimal notation but some trails with variable has shown that times +was very closed. + +First line indicates the numbers of digits for both operands. +Operands were build like this: +\begin{itemize} +\item $\mathrm{A} = 1$ et $\mathrm{B} = 9$ for one digit; +\item $\mathrm{A} = 12$ et $\mathrm{B} = 98$ for two digits; +\item $\mathrm{A} = 123$ et $\mathrm{B} = 987$ for three digits; +\item $\mathrm{A} = 12345$ et $\mathrm{B} = 98765$ for five digits; +\item $\mathrm{A} = 1234567890$ et $\mathrm{B} = 9876543210$ for ten + digits; +\item $\mathrm{A} = 12345678901234567890$ et $\mathrm{B} = + 98765432109876543210$ for twenty digits; +\end{itemize} +Here is results, some comments follow: + +\bigskip\noindent\hbox to\linewidth{\hss + \begin{tabular}{|r|*{6}{l|}} + \cline{2-7} + \multicolumn{1}{l|}{} & + \multicolumn{1}{c|}{1} & + \multicolumn{1}{c|}{2} & + \multicolumn{1}{c|}{3} & + \multicolumn{1}{c|}{5} & + \multicolumn{1}{c|}{10} & + \multicolumn{1}{c|}{20} \\\hline + \verb+\opadd*{A}{B}{r}+ & + 1.1 & 1.4 & 1.6 & 2.1 & 3.3 & 5.8 \\\cline{2-7} + \verb+\opadd*{B}{A}{r}+ & + 1.1 & 1.4 & 1.6 & 2.1 & 3.3 & 5.8 \\\hline + \verb+\opsub*{A}{B}{r}+ & + 1.7 & 2.1 & 2.4 & 3.0 & 4.8 & 8.3 \\\cline{2-7} + \verb+\opsub*{B}{A}{r}+ & + 1.5 & 1.7 & 2.0 & 2.6 & 4.0 & 7.0 \\\hline + \verb+\opmul*{A}{B}{r}+ & + 4.6 & 6.3 & 8.2 & 12.8 & 29.9 & 87.0 \\\cline{2-7} + \verb+\opmul*{B}{A}{r}+ & + 5.0 & 6.6 & 8.5 & 13.2 & 30.3 & 87.8 \\\hline + \verb+\opdiv*{A}{B}{q}{r}+ & + 46.4 & 53.8 & 53.8 & 64.3 & 85.8 & 124.7 \\\cline{2-7} + \verb+\opdiv*{B}{A}{q}{r}+ & + 12.4 & 48.9 & 55.7 & 58.6 & 72.8 & 111.0 \\\hline + \verb+\opdiv*[maxdivstep=5]{A}{B}{q}{r}+ & + 26.8 & 30.0 & 32.6 & 37.6 & 49.5 & 73.5 \\\cline{2-7} + \verb+\opdiv*[maxdivstep=5]{B}{A}{q}{r}+ & + 12.4 & 29.1 & 32.6 & 35.2 & 43.3 & 67.9 \\\hline + \verb+\opidiv*{A}{B}{q}{r}+ & + 10.8 & 12.2 & 13.5 & 16.0 & 22.3 & 35.5 \\\cline{2-7} + \verb+\opidiv*{B}{A}{q}{r}+ & + 11.6 & 13.0 & 14.2 & 16.6 & 23.0 & 36.7 \\\hline + \verb+\opidiv*{A}{2}{q}{r}+ & + 10.7 & 12.0 & 15.3 & 22.3 & 42.9 & 83.0 \\\hline + \end{tabular} + \hss +} +\par\bigskip +It is normal that inversion of operands don't have sensible influence +for addition. Then, it could be strange that there is influence for +substraction. In fact, when the second operand is bigger than the +second one, there is additional process (double inversion, operation +on the sign of the result). + +It is normal that division time is greater than the multiplication +one. It could be abnormal that division seems catch up! In fact, the +multiplication complexity grows quickly with the operand length. In +the other hand, division complexity is stopped +by \parameter{maxdivstep} parameter. It is clear on example where +there is only five steps. + +Some results seems odd. For instance \verb+\opdiv*{9}{1}{q}{r}+ is +very fast. These is due to the one digit quotient. +\verb+\opdiv*{123}{987}{q}{r}+, even more odd, is rather fast. Here, +explanation is quite subtle: this is due to many zeros in the +quotient. + +When operands have comparable length, euclidian division is much +faster than non euclidian one. This is because quotient has few +digits (only one for all the numbers \texttt{A} and \texttt{B}). The +last line of the table is more relevant for this operation time. + +All these remarks are written to put the emphasis on the difficulty to +evaluate the compilation time: it depends on too many parameters. On +the other hand, this table give a pretty good idea of what can be +expected. +\index{compilation time|)}\index{time (calculation)|)}% + +\newpage +\section{Macros List} +\label{sec:Liste des macros} +\index{macros!table of|(}% +\noindent\begin{longtable}{|l|p{6.3cm}|} + \hline + \multicolumn{1}{|c|}{\textbf{Macro}} & + \multicolumn{1}{c|}{\textbf{Description}} \\\hline\hline + \endfirsthead + \hline + \multicolumn{1}{|c|}{\textbf{Macro}} & + \multicolumn{1}{c|}{\textbf{Description}} \\\hline\hline + \endhead + \hline + \multicolumn{2}{|c|}{$\ldots$ to be continued $\ldots$}\\ + \hline + \endfoot + \hline + \endlastfoot + \verb+\opabs{n}{N}+ & + \verb+N+ stores the absolute value of \verb+n+. \\\hline + \verb+\opadd[P]{n1}{n2}+ & + Displays result of \verb-n1+n2-. \\\hline + \verb+\opadd*{n1}{n2}{N}+ & + Calcules \verb-n1+n2- and put result in \verb+N+. \\\hline + \verb+\opcastingoutelevens{n}{N}+ & + Calcules difference (modulo 11) of sum of rank odd digits and sum of + rank even digits of \verb+n+ and put the result in \verb+N+.\\\hline + \verb+\opcastingoutnines{n}{N}+. & + Calcules sum modulo 9 of digits of \verb+n+ and put result in + \verb+N+. \\\hline + \verb+\opceil{n}{T}{N}+ & + Places in \verb+N+ the approximation (ceiling) of \verb+n+ to rank + \verb+T+. \\\hline + \verb+\opcmp{n1}{n2}+ & + Compares numbers \verb+n1+ and \verb+n2+ and setup the tests + \verb+\ifopeq+, \verb+\ifopneq+, \verb+\ifopgt+, \verb+\ifopge+, + \verb+\ifople+ et \verb+\ifoplt+. \\\hline + \verb+\opcopy{n}{N}+ & + Copy number \verb+n+ in \verb+N+. \\\hline + \verb+\opdecimal{n}{N}+ & + Copy decimal part (positive integer number) of \verb+n+ in + \verb+N+. \\\hline + \verb+\opdecimalwidth{n}{N}+ & + \verb+N+ stores the width of decimal part of number \verb+n+. + \\\hline + \verb+\opdisplay[P]{S}{n}+ & + Display number \verb+n+ width style \verb+S+ puting each figure in a + box which have a width of \verb+\opcolumnwidth+ and a height of + \verb+\oplineheight+. \\\hline + \verb+\opdiv[P]{n1}{n2}+ & + Display result of n1/n2. \\\hline + \verb+\opdiv*[P]{n1}{n2}{N1}{N2}+ & + Calculates \verb+n1/n2+, put the quotient in \verb+N1+ and the + remainder in \verb+N2+. \\\hline + \verb+\opdivperiod{T1}{T2}{N}+ & + Calculates length of period of \verb+T1+ divide by \verb+T2+ and put + the result in \verb+N+. \\\hline + \verb+\opexport[P]{n}\cmd+ & + Copy number \verb+n+ in macro \verb+\cmd+. \\\hline + \verb+\opexpr[P]{F}{N}+ & + Evaluates formula \texttt{F} and put the final result in + \texttt{N}. \\\hline + \verb+\opfloor{n}{T}{N}+ & + Put in \verb+N+ the apprimation (floor) of \verb+n+ at rank + \verb+T+. \\\hline + \verb+\opgcd{T1}{T2}{N}+ & + Calculates gcd of \verb+T1+ and \verb+T2+ and put result in + \verb+N+. \\\hline + \verb+\opgetdecimaldigit{n}{T}{N}+ & + Build the number \verb+N+ with the only digit in slot + \verb+T+ of decimal part of \verb+n+. \\\hline + \verb+\opgetdigit{n}{T}{N}+ & + Build the number \verb+N+ with the only digit in slot + \verb+T+ of number \verb+n+. \\\hline + \verb+\opgetintegerdigit{n}{T}{N}+ & + Build the number \verb+N+ width the only digit in slot + \verb+T+ of integer part of \verb+n+. \\\hline + \verb+\ophline(T1,T2){T3}+ & + Draw a horizontal rule of length \verb+T3+, of thickness + \verb+hrulewidth+, and which begin at \verb+(T1,T2)+ in relation to + reference point. \\\hline + \verb+\opidiv[P]{n1}{n2}+ & + Display the result of \verb+n1/n2+. (euclidian division, that is, + with integer division) \\\hline + \verb+\opidiv*{n1}{n2}{N1}{N2}+ & + Calculates \verb+n1/n2+ (euclidian division), put quotient + (integer) in \verb+N1+ and remainder (between 0 (include) and + \verb+|n2|+ (exclude)) in \verb+N2+. \\\hline + \verb+\opinteger{n}{N}+ & + Copy integer part (positive integer number) of \verb+n+ + in \verb+N+. \\\hline + \verb+\opintegerwidth{n}{N}+ & + Number \verb+N+ stores the width of integer part of number \verb+n+. + \\\hline + \verb+\oplput(T1,T2){}+ & + Put \verb++ to the right of the point with coordinates + \verb+(T1,T2)+ in relation to reference point. \\\hline + \verb+\opmul[P]{n1}{n2}+ & + Display result of \verb+n1*n2+. \\\hline + \verb+\opmul*{n1}{n2}{N}+ & + Calculates \verb+n1*n2+ and put the result in \verb+N+. \\\hline + \verb+\opneg{n}{N}+ & + Number \verb+N+ stores opposite of \verb+n+. \\\hline + \verb+\oppower{n}{T}{N}+ & + Calculates \verb+n+ to the power of \verb+T+ and put the result in + \verb+N+. \\\hline + \verb+\opprint{n}+ & + Display number \verb+n+ in a direct way. \\\hline + \verb+\opround{n}{T}{N}+ & + Put in \verb+N+ the approximation of \verb+n+ at rank \verb+T+. + \\\hline + \verb+\oprput(T1,T2){}+ & + Put \verb++ to the left of the point with coordinates + \verb+(T1,T2)+ in relation to reference point. \\\hline + \verb+\opset{L}+ & + Allocates globally \package{xlop} parameters given in the list + \verb+L+. \\\hline + \verb+\opsetdecimaldigit{n}{T}{N}+ & + Modify the digit of rank \verb+T+ in decimal part of \verb+N+ in + order to have the value \verb+n+ for this digit. \\\hline + \verb+\opsetdigit{n}{T}{N}+ & + Modify the digit of rank \verb+T+ of \verb+N+ in + order to have the value \verb+n+ for this digit. \\\hline + \verb+\opsetintegerdigit{n}{T}{N}+ & + Modify the digit of rank \verb+T+ in integer part of \verb+N+ in + order to have the value \verb+n+ for this digit. \\\hline + \verb+\opsub[P]{n1}{n2}+ & + Display result of \verb+n1-n2+. \\\hline + \verb+\opsub*{n1}{n2}{N}+ & + Calculates \verb+n1-n2+ and put the result in \verb+N+. \\\hline + \verb+\opunzero{N}+ & + Delete non-significant zeros of \verb+N+. \\\hline + \verb+\opvline(T1,T2){T3}+ & + Draw a vertical ruleof length \verb+T3+, of thickness + \verb+hrulewidth+ and which begin at \verb+(T1,T2)+ in relation to + reference point. \\\hline + \verb+\opwidth{n}{N}+ & + Number \verb+N+ stores number of digits of number \verb+n+. \\\hline +\end{longtable}\index{macros!table of|)} + +In this table, parameters: +\begin{itemize} +\item \texttt{n} and \texttt{ni} (where \texttt{i} is an index) + indicate that parameter must be a number given in decimal form or a + variable name; +\item \texttt{N} and \texttt{Ni} (where \texttt{i} is an index) + indicate that parameter must be a number given in decimal form or a + variable name; +\item \texttt{[P]} indicates that the macro accept an optional + parameter which allow to modify parameter of \package{xlop}; +\item \texttt{T} and \texttt{Ti} (where \texttt{i} is an index) + indicate that parameter must be a number given in decimal form or a + variable name but must be less than numbers acceptable by \TeX{}, + that is, $-2147483648 \le \mathtt{T} \le 2147483647$. +\end{itemize} + +\section{Parameter list} +\label{sec:Liste des parametres} +\index{parameter@parameter!table of|(}% +\begingroup +\advance\hoffset by-1.75cm \advance\linewidth by1.75cm +\begin{longtable}{|l|l|p{7cm}|} + \hline + \multicolumn{1}{|c|}{\textbf{Parameter}} & + \multicolumn{1}{c|}{\textbf{Default}} & + \multicolumn{1}{c|}{\textbf{Signification}} \\\hline\hline + \endfirsthead + \hline + \multicolumn{1}{|c|}{\textbf{Parameter}} & + \multicolumn{1}{c|}{\textbf{Default}} & + \multicolumn{1}{c|}{\textbf{Signification}} \\\hline\hline + \endhead + \hline + \multicolumn{3}{|c|}{$\ldots$ to be continued $\ldots$}\\ + \hline + \endfoot + \hline + \endlastfoot + \verb+afterperiodsymbol+ & + \verb+$\ldots$+ & + Symbol used after a period of a division. \\\hline + \verb+approxsymbol+ & + \verb+$\approx$+ & + Symbol used as approximation relation in inline operations. \\\hline + \verb+equalsymbol+ & + \verb+{$=$}+ & + Symbol used as equality relation in inline operations. \\\hline + \verb+addsymbol+ & + \verb-$+$- & + Symbol used as addition operator. \\\hline + \verb+subsymbol+ & + \verb+$-$+ & + Symbol used as substraction operator. \\\hline + \verb+mulsymbol+ & + \verb+$\times$+ & + Symbol used as multiplication operator. \\\hline + \verb+divsymbol+ & + \verb+$\div$+ & + Symbol used as multiplication operator for inline + operations. \\\hline + \verb+decimalsepsymbol+ & + \verb+.+ & + Symbol used as decimal separator. \\\hline + \verb+strikedecimalsepsymbol+ & + & + Symbol used as decimal separator moved in dividend and divisor for + display division. \\\hline + \verb+shiftintermediarysymbol+ & + \verb+$\cdot$+ & + Symbol used to show intermediary numbers shifting for display + multiplication. \\\hline + \verb+displayshiftintermediary+ & + \verb+shift+ & + Indicates that the shifting character for multiplications will be + displayed only for additional shifting (value \verb+shift+), for + all the shifting (value \verb+all+), or never (value + \verb+none+). \\\hline + \verb+voperation+ & + \verb+bottom+ & + Vertical alignement for displayed operation. The value \verb+bottom+ + indicates that the bottom of operation will be aligned with + baseline. The value \verb+top+ indicates that the top of operation + will be aligned with baseline. The value \verb+center+ indicates + that operation will be verticaly centred with baseline. \\\hline + \verb+voperator+ & + \verb+center+ & + Vertical alignement for operators in displayed operations. The value + \verb+top+ put operator at the level of first operand. The value + \verb+bottom+ put operator at the level of second operand. The value + \verb+center+ put operator between operands. \\\hline + \verb+hfactor+ & + \verb+decimal+ & + Sort of operands alignement for displayed operation. The value + \verb+decimal+ indicates an alignement on decimal separator. The + value \verb+right+ indicates a flushright alignement. \\\hline + \verb+vruleperiod+ & + \verb+-0.2+ & + Vertical position of rule which indicates period of quotient for + inline division. \\\hline + \verb+dividendbridge+ & + \verb+false+ & + Indicates if there is a ``bridge'' above dividend. \\\hline + \verb+shiftdecimalsep+ & + \verb+both+ & + Indicates how shift decimal separator into operands for a displayed + division. The value \verb+both+ indicates that shifting are made on + both divisor and dividend in order to make integer numbers. The + value \verb+divisor+ indicates that the shifting must give an + integer divisor. The value \verb+none+ indicates that there is no + shifting. \\\hline + \verb+maxdivstep+ & + \verb+10+ & + Maximal number of steps in division. \\\hline + \verb+safedivstep+ & + \verb+50+ & + Maximal number of steps in division when there is a period to + reach. \\\hline + \verb+period+ & + \verb+false+ & + Indicates if division must be stoped when a whole period is + reached. \\\hline + \verb+deletezero+ & + \verb+true+ & + Indicates that non-significant zeros are displayed (\verb+false+) or + deleted (\verb+true+). \\\hline + \verb+carryadd+ & + \verb+true+ & + Indicates that carries are displayed (\verb+true+) for displayed + additions. \\\hline + \verb+carrysub+ & + \verb+false+ & + Indicates that carries are displayed (\verb+true+) for displayed + substractions. \\\hline + \verb+offsetcarry+ & + \verb+-0.35+ & + Horizontal offset for carries into displayed substractions. \\\hline + \verb+style+ & + \verb+display+ & + Indicates tha operation are inline (\verb+text+) or displayed + (\verb+display+). \\\hline + \verb+displayintermediary+ & + \verb+nonzero+ & + Indicates that all intermediary results are displayed (\verb+all+), + only non null ones are displayed (\verb+nonzero+), or any + intermediary result isn't displayed into displayed multiplications + and divisions. \\\hline + \verb+lastcarry+ & + \verb+false+ & + Indicates that carry with no figure just below it must be displayed + (\verb+true+), or not (\verb+false+). \\\hline + \verb+parenthesisnegative+ & + \verb+none+ & + Behavior to display negative numbers in inline operations. The value + \verb+none+ displays them without parenthesis. The value \verb+all+ + displays them always with parenthesis. The value \verb+last+ display + parenthesis except for first operand of an expression. \\\hline + \verb+columnwidth+ & + \verb+2ex+ & + With of box for one figure. \\\hline + \verb+lineheight+ & + \verb+\baselineskip+ & + Height of box for one figure. \\\hline + \verb+decimalsepwidth+ & + \verb+0pt+ & + Width of box that hold the decimal separator. \\\hline + \verb+decimalsepoffset+ & + \verb+0pt+ & + Horizontal offset for decimal separator. \\\hline + \verb+hrulewidth+ & + \verb+0.4pt+ & + Thickness of horizontal rules. \\\hline + \verb+vrulewidth+ & + \verb+0.4pt+ & + Thickness of vertical rules. \\\hline + \verb+behaviorsub+ & + \verb+silent+ & + \package{xlop} behavior for an ``impossible'' substraction, that is, + a substraction with two positive operands, the second greater + than the first one. The value \verb+silent+ does operation swapping + the two operands in a slient way. With the value \verb+warning+, + there are also a swapping but \package{xlop} gives a warning. The + value \verb+error+ display an error message and operation isn't + processed. \\\hline + \verb+country+ & + \verb+french+ & + Indicates the displayed operation behavior depending of + contry. Package \package{xlop} put forward only \verb+french+, + \verb+american+, and \verb+russian+ but these different ways to + display operations aren't encoded in version 0.23. \\\hline + \verb+operandstyle+ & + & + Style for operands. \\\hline + \verb+resultstyle+ & + & + Style for results. \\\hline + \verb+remainderstyle+ & + & + Style for remainders. \\\hline + \verb+intermediarystyle+ & + & + Style for intermediary results (intermediary numbers in + multiplication and number to substract in division when successive + substractions are displayed). \\\hline + \verb+carrystyle+ & + \verb+\scriptsize+ & + Style for carries. The default value when compilation are made + without \LaTeX{} is \verb+\sevenrm+. \\\hline +\end{longtable}\index{parameter@parameter!table of|)} +\endgroup + +\chapter{Tricks} +\label{chap:Trucs et astuces} +\section{\package{xlop} vs. \package{calc} and \package{fp}} +You could believe that \package{xlop} can replace package such +\package{calc}\index{package!calc}\index{calc} and +\package{fp}\index{package!fp}\index{fp}. In fact, that is not so +simple. Obviously \package{xlop} can do complex calculations, on arbitrary +long numbers but, unlike \package{calc}, it don't allow to process +directly dimensions. Comparison with \package{fp} is somewhere more +realistic but remember that \package{xlop} can make memory usage too +high. + +If you want to process calculations on length\index{length}, you can use +that a dimen register allocation to a counter gives a number which +correspond to this length with unit \texttt{sp}. +\begin{CenterExample}[xrightmargin=0pt] + \newcommand\getsize[2]{% + \dimen0=#1\relax + \count255=\dimen0 + \opcopy{\the\count255}{#2}} + \getsize{1pt}{r}$1\,\mathrm{pt}=\opprint{r}\,\mathrm{sp}$\quad + \getsize{1pc}{r}$1\,\mathrm{pc}=\opprint{r}\,\mathrm{sp}$\quad + \getsize{1in}{r}$1\,\mathrm{in}=\opprint{r}\,\mathrm{sp}$\quad + \getsize{1bp}{r}$1\,\mathrm{bp}=\opprint{r}\,\mathrm{sp}$\quad + \getsize{1cm}{r}$1\,\mathrm{cm}=\opprint{r}\,\mathrm{sp}$\quad + \getsize{1mm}{r}$1\,\mathrm{mm}=\opprint{r}\,\mathrm{sp}$\quad + \getsize{1dd}{r}$1\,\mathrm{dd}=\opprint{r}\,\mathrm{sp}$\quad + \getsize{1cc}{r}$1\,\mathrm{cc}=\opprint{r}\,\mathrm{sp}$\quad + \getsize{1sp}{r}$1\,\mathrm{sp}=\opprint{r}\,\mathrm{sp}$\quad +\end{CenterExample} +However, don't forget that the \package{xlop} main goal is to +\emph{display} operations. + +With this \macro{getsize} macro, it is possible to realise +calculations on length. +\begin{SideBySideExample} + \newcommand\getsize[2]{% + \dimen0=#1\relax + \count255=\dimen0 + \opcopy{\the\count255}{#2}} + \getsize{1cm}{u}% + \getsize{\textwidth}{w}% + \getsize{\textheight}{h}% + \opexpr{w*h/u^2}{S}% + \opround{S}{2}{S}% + Surface of spread is + \opprint{S}\,$\mathrm{cm}^2$ +\end{SideBySideExample} + +\section{Complex Operations} +\label{sec:Creation d'operations complexes} +Use of \package{xlop} macros with loop of \TeX{} allow to create +operations as you want. Here, we give only two examples. The first one +can express a number as a product of prime factors, the second one is +a general calculation for continued +fraction.\index{number!prime}\index{loop|(}% +\index{product of prime factors} +\begin{Verbatim}[xrightmargin=0pt] + \newcount\primeindex + \newcount\tryindex + \newif\ifprime + \newif\ifagain + \newcommand\getprime[1]{% + \opcopy{2}{P0}% + \opcopy{3}{P1}% + \opcopy{5}{try} + \primeindex=2 + \loop + \ifnum\primeindex<#1\relax + \testprimality + \ifprime + \opcopy{try}{P\the\primeindex}% + \advance\primeindex by1 + \fi + \opadd*{try}{2}{try}% + \ifnum\primeindex<#1\relax + \testprimality + \ifprime + \opcopy{try}{P\the\primeindex}% + \advance\primeindex by1 + \fi + \opadd*{try}{4}{try}% + \fi + \repeat + } + \newcommand\testprimality{% + \begingroup + \againtrue + \global\primetrue + \tryindex=0 + \loop + \opidiv*{try}{P\the\tryindex}{q}{r}% + \opcmp{r}{0}% + \ifopeq \global\primefalse \againfalse \fi + \opcmp{q}{P\the\tryindex}% + \ifoplt \againfalse \fi + \advance\tryindex by1 + \ifagain + \repeat + \endgroup + } +\end{Verbatim} +\newcount\primeindex +\newcount\tryindex +\newif\ifprime +\newif\ifagain +\newcommand\getprime[1]{% + \opcopy{2}{P0}% + \opcopy{3}{P1}% + \opcopy{5}{try} + \primeindex=2 + \loop + \ifnum\primeindex<#1\relax + \testprimality + \ifprime + \opcopy{try}{P\the\primeindex}% + \advance\primeindex by1 + \fi + \opadd*{try}{2}{try}% + \ifnum\primeindex<#1\relax + \testprimality + \ifprime + \opcopy{try}{P\the\primeindex}% + \advance\primeindex by1 + \fi + \opadd*{try}{4}{try}% + \fi + \repeat +} +\newcommand\testprimality{% + \begingroup + \againtrue + \global\primetrue + \tryindex=0 + \loop + \opidiv*{try}{P\the\tryindex}{q}{r}% + \opcmp{r}{0}% + \ifopeq \global\primefalse \againfalse \fi + \opcmp{q}{P\the\tryindex}% + \ifoplt \againfalse \fi + \advance\tryindex by1 + \ifagain + \repeat + \endgroup +} + +With this code, we can create a prime numbers list (here the 20~first +ones). +\begin{SideBySideExample} + \getprime{20}% + \opprint{P0}, \opprint{P1}, \ldots, + \opprint{P9}, \ldots \opprint{P19}. +\end{SideBySideExample} + +Note that this code is very bad: it is very slow and don't give +anything against native \TeX{} operations. It is only a educational +example. Note also that the tricks to put loop into loop with macro +\verb+\testprimality+ inside a group. \package{xlop} operations give +global results.\index{global allocation} + +Once you have your prime numbers ``table'', you can use it to +write a number as product of prime number. +\begin{CenterExample}[xrightmargin=0pt] + \newcommand\primedecomp[2][nil]{% + \begingroup + \opset{#1}% + \opcopy{#2}{NbtoDecompose}% + \opabs{NbtoDecompose}{NbtoDecompose}% + \opinteger{NbtoDecompose}{NbtoDecompose}% + \opcmp{NbtoDecompose}{0}% + \ifopeq + I refuse to factorize zero. + \else + \setbox1=\hbox{\opdisplay{operandstyle.1}% + {NbtoDecompose}}% + {\setbox2=\box2{}}% + \count255=1 + \primeindex=0 + \loop + \opcmp{NbtoDecompose}{1}\ifopneq + \opidiv*{NbtoDecompose}{P\the\primeindex}{q}{r}% + \opcmp{0}{r}\ifopeq + \ifvoid2 + \setbox2=\hbox{% + \opdisplay{intermediarystyle.\the\count255}% + {P\the\primeindex}}% + \else + \setbox2=\vtop{% + \hbox{\box2} + \hbox{% + \opdisplay{intermediarystyle.\the\count255}% + {P\the\primeindex}}} + \fi + \opcopy{q}{NbtoDecompose}% + \advance\count255 by1 + \setbox1=\vtop{% + \hbox{\box1} + \hbox{% + \opdisplay{operandstyle.\the\count255}% + {NbtoDecompose}} + }% + \else + \advance\primeindex by1 + \fi + \repeat + \hbox{\box1 + \kern0.5\opcolumnwidth + \opvline(0,0.75){\the\count255.25} + \kern0.5\opcolumnwidth + \box2}% + \fi + \endgroup + } + + \getprime{20}% + \primedecomp[operandstyle.2=\red, + intermediarystyle.2=\red]{252} +\end{CenterExample} +Note the use of group for the whole macro in order to protect +\package{xlop} parameter modifications.% +\index{parameter!local modification} Note also that void parameter +aren't allowed. It's not a bug, it's a feature. Author thinks that a +user who write brackets without anything between these brackets is +going to make a mistake. To obviate this +prohibition\index{parameter!void}, there is the particular +parameter \parameter{nil} which has exactly this rôle. +\index{loop|)} + +Finally, note the trick \verb+{\setbox2=\box2}+ to obtain a void box +register, and final manipulations to show the vertical rule in a +easy-to-read way. + +The second example allow to calculates a continued fraction like: +\def\dfrac#1#2{\frac{\displaystyle #1}{\displaystyle #2}} +\[a_0+\dfrac{1}{a_1+\dfrac{1}{a_2+\dfrac{1}{a_3+\cdots}}}\] +giving the sequence $a_0,a_1,a_2,a_3,\ldots$ to the macro. This +example gives fractions corresponding to gold number, and square root +for~2 and~3. +\makeatletter +\begin{CenterExample}[xrightmargin=0pt] + \begingroup + \long\gdef\continuedfraction#1#2{% + \let\@mirror\relax + \@for\op@Nb:=#1\do + {% + \ifx\@mirror\relax + \edef\@mirror{\op@Nb}% + \else + \edef\@mirror{\op@Nb,\@mirror}% + \fi + }% + \let\Op@result\relax + \@for\op@Nb:=\@mirror\do + {% + \ifx\Op@result\relax + \opcopy{\op@Nb}{result}% + \else + \opexpr{\op@Nb+1/result}{result}% + \fi + }% + \opcopy{result}{#2}% + } + \endgroup + \continuedfraction{1,1,1,1,1,1,1,1,1,1,1,1}{r}\opprint{r}\quad + \continuedfraction{1,2,2,2,2,2,2,2,2,2,2,2}{r}\opprint{r}\quad + \continuedfraction{1,1,2,1,2,1,2,1,2,1,2,1}{r}\opprint{r} +\end{CenterExample} +\makeatother +It does no harm just this once, we use \LaTeX{} commands for the +loop. + +\section{Direct Access to Number} +\label{sec:Acces direct aux nombres} +When a number is saved in a \package{xlop} variable, it is possible to +process with it in many different ways. However, in certain +situations, you would creat you own macro or use external macro giving +such numbers as parameter. + +Giving directly \verb+\opprint{var}+ is ineffective since this macro +is a complex a gives side effect. It is necessary to access directly +to this number. When a variable hold a number, \package{xlop} creates +a macro +\texttt{$\backslash$Op@var}\index{Opvar@\texttt{\boi {Op\at var}}} +which contain this number. Note the uppercase ``O'' and the lowercase +``p''. The at sign is here to do this definition a private one, that +is, you have to enclose it with \macro{makeatletter} and +\macro{makeatother} to access it (or \macro{catcode @=11} in \TeX). +\begin{SideBySideExample} + \opcopy{1234}{a}\opcopy{56}{b}% + \opmul*{a}{b}{r}% + \makeatletter + \newcolumntype{.}{D{.}{.}{-1}} + \begin{tabular}{l.} + & \Op@a \\ + $\times$ & \Op@b \\ + $=$ & \Op@r + \end{tabular} + \makeatother +\end{SideBySideExample} + +Note that this way of doing don't work when decimal separator is +between braces since macro \verb+\opprint{var}+ contain such +braces. In this case, the simplest is to use \macro{opexport} macro +(see page~\pageref{macro-opexport}). + +\chapter{Future Versions} +\label{chap:Versions futures} +Version of \package{xlop} package is~0.23 which is only a debuging +version of version~0.2, which is itself a correcting version of +version~0.1 (first public release). The next release will be +version~0.3 and its ``stable'' version will be version~0.4. + +The features of version~0.3 aren't definitively fixed but there are +some points planned: +\begin{itemize} +\item international version for posées; +\item opérations from 2 to 36~basis; +\item additional high level functions with roots (\macro{oproot} for + any roots and \macro{opsqrt} for square root), exponential function, + logarithm, trigonometric functions (direct, inverse, hyperbolic); +\item macro to have a formated writing, that is, write a number where + length of decimal part and integer part are given (if these widths + are not the ones of the number, there will be overflow or filling); + this macro was present in version~0.1 and allow to display numbers + decimal aligned, right aligned, or left aligned; +\item macro for addition with more than two operands; +\item parameter for scientific or engineer notation; +\item macro to allow to write a multi-line number and/or with thousand + separator; +\item carries for multiplications; +\item make public the successive remainders of a division; +\item negative values of \parameter{maxdivstep} and + \parameter{safedivstep} parameters will take acount of decimal digit + of quotient. +\end{itemize} + +For all requests or bug report, the author will be grateful to you to +contact him at: +\begin{verbatim} + Jean-Come.Charpentier@wanadoo.fr +\end{verbatim} +placing the word ``xlop'' in the subject in order to help my spam killer. + +It would be nice to have a hacker manual which explain in details the +source. This tool could be usefull in order to improve +\package{xlop}. Unfortunately, the current code has more +than~4000~lines and the work to do that may well be too long. + +%\printindex +\chapter{Index} +\label{chap:index} +\begin{multicols}{2} +\makeatletter +\parindent \z@\relax +\parskip \z@ \@plus.3\p@\relax +\let\item\@idxitem +\makeatother +\renewenvironment{theindex}{}{}% +\input\jobname.ind +\end{multicols} +\end{document} diff --git a/Master/texmf-dist/source/generic/xlop/manual.sty b/Master/texmf-dist/source/generic/xlop/manual.sty index a186256b849..1047dd3766d 100644 --- a/Master/texmf-dist/source/generic/xlop/manual.sty +++ b/Master/texmf-dist/source/generic/xlop/manual.sty @@ -1,12 +1,16 @@ \usepackage[T1]{fontenc} \usepackage[latin1]{inputenc} -\usepackage{lmodern} +\usepackage{fourier} +\usepackage[scaled]{helvet} +\usepackage[scaled]{luximono} \usepackage{makeidx} \usepackage{longtable} \usepackage{multicol} \usepackage{pst-node} \usepackage{fvrb-ex} \usepackage{geometry} +\usepackage{hyperref} +\usepackage{microtype} \usepackage{xlop} \fvset{xrightmargin=5cm,frame=single,fontsize=\small} @@ -38,4 +42,5 @@ \newcommand\bull{\vrule width3pt height4pt depth-1pt} +\newcounter{stuff} \makeindex diff --git a/Master/texmf-dist/tex/generic/xlop/xlop.sty b/Master/texmf-dist/tex/generic/xlop/xlop.sty index 8c672c8d15e..65de248f1f0 100644 --- a/Master/texmf-dist/tex/generic/xlop/xlop.sty +++ b/Master/texmf-dist/tex/generic/xlop/xlop.sty @@ -1,3 +1,3 @@ -\ProvidesPackage{xlop}[2006/01/04 package wrapper for xlop.tex] +\ProvidesPackage{xlop}[2009/12/02 package wrapper for xlop.tex] \input xlop.tex \endinput diff --git a/Master/texmf-dist/tex/generic/xlop/xlop.tex b/Master/texmf-dist/tex/generic/xlop/xlop.tex index dea98da45d0..004adf7c8f1 100644 --- a/Master/texmf-dist/tex/generic/xlop/xlop.tex +++ b/Master/texmf-dist/tex/generic/xlop/xlop.tex @@ -1,5 +1,5 @@ -\def\fileversion{0.22} -\def\filedate{2006/01/04} +\def\fileversion{0.23} +\def\filedate{2009/12/02} %% %% xlop.tex: %% eXtra Large OPeration macros for Generic TeX. @@ -21,12 +21,13 @@ \let\xlopLoaded\endinput \edef\opAtCode{\the\catcode`\@} \catcode`\@=11\relax -\newcount\count@z -\newcount\count@i -\newcount\count@ii -\newcount\count@iii -\newcount\count@iv -\newcount\count@v +\newcount\op@count@z +\newcount\op@count@i +\newcount\op@count@ii +\newcount\op@count@iii +\newcount\op@count@iv +\newcount\op@count@v +\newcount\op@count@vi \newtoks\op@currentstyle \expandafter\ifx\csname @latexerr\endcsname\relax \long\def\@ifundefined#1#2#3{% @@ -97,17 +98,17 @@ #1^^J\@spaces See documentation for further information.^^J}% \endgroup } -\let\@nil\relax +\let\op@nil\relax \def\opset#1{% - \Pop@set#1,\@nil + \Pop@set#1,\op@nil \ifop@error\op@errorwrite\fi \ignorespaces } \def\Pop@set#1,{% - \Pop@@set#1==\@nil - \@ifnextchar\@nil{\@gobble}{\Pop@set}% + \Pop@@set#1==\op@nil + \@ifnextchar\op@nil{\@gobble}{\Pop@set}% } -\def\Pop@@set#1=#2=#3\@nil{% +\def\Pop@@set#1=#2=#3\op@nil{% \@ifundefined{pOP@#1}% {\Pop@@@set#1.={#2}} {\@nameuse{pOP@#1}{#2}}% @@ -469,19 +470,19 @@ \opset{carrystyle=\scriptsize} \fi -\count@z=`\0 \edef\op@numbegin{\the\count@z} -\count@z=`\9 \edef\op@numend{\the\count@z} -\count@z=`\+ \edef\op@plus{\the\count@z} -\count@z=`\- \edef\op@minus{\the\count@z} -\count@z=`\* \edef\op@multiply{\the\count@z} -\count@z=`\/ \edef\op@divide{\the\count@z} -\count@z=`\: \edef\op@idivide{\the\count@z} -\count@z=`\^ \edef\op@pow{\the\count@z} -\count@z=`\. \edef\op@dot{\the\count@z} -\count@z=`\, \edef\op@comma{\the\count@z} -\count@z=`\( \edef\op@lparenthesis{\the\count@z} -\count@z=`\) \edef\op@rparenthesis{\the\count@z} -\count@z=`\ \edef\op@space{\the\count@z} +\op@count@z=`\0 \edef\op@numbegin{\the\op@count@z} +\op@count@z=`\9 \edef\op@numend{\the\op@count@z} +\op@count@z=`\+ \edef\op@plus{\the\op@count@z} +\op@count@z=`\- \edef\op@minus{\the\op@count@z} +\op@count@z=`\* \edef\op@multiply{\the\op@count@z} +\op@count@z=`\/ \edef\op@divide{\the\op@count@z} +\op@count@z=`\: \edef\op@idivide{\the\op@count@z} +\op@count@z=`\^ \edef\op@pow{\the\op@count@z} +\op@count@z=`\. \edef\op@dot{\the\op@count@z} +\op@count@z=`\, \edef\op@comma{\the\op@count@z} +\op@count@z=`\( \edef\op@lparenthesis{\the\op@count@z} +\op@count@z=`\) \edef\op@rparenthesis{\the\op@count@z} +\op@count@z=`\ \edef\op@space{\the\op@count@z} \newcount\op@parenthesis \newcount\op@token \newcount\op@stack @@ -518,17 +519,17 @@ \op@isplusfalse \op@isminusfalse \op@isdecimalsepfalse - \count@z=`#1\relax - \ifnum\count@z=\op@plus\relax + \op@count@z=`#1\relax + \ifnum\op@count@z=\op@plus\relax \op@isplustrue - \else\ifnum\count@z=\op@minus\relax + \else\ifnum\op@count@z=\op@minus\relax \op@isminustrue - \else\ifnum\count@z=\op@dot\relax + \else\ifnum\op@count@z=\op@dot\relax \op@isdecimalseptrue - \else\ifnum\count@z=\op@comma\relax + \else\ifnum\op@count@z=\op@comma\relax \op@isdecimalseptrue - \else\ifnum\count@z<\op@numbegin\relax - \else\ifnum\count@z>\op@numend\relax + \else\ifnum\op@count@z<\op@numbegin\relax + \else\ifnum\op@count@z>\op@numend\relax \else \op@isdigittrue \fi\fi\fi\fi\fi\fi @@ -536,7 +537,7 @@ \def\op@split#1#2{% \begingroup \edef\op@arg{#1}% - \expandafter\op@readnumber\op@arg\@nil + \expandafter\op@readnumber\op@arg\op@nil \ifop@error \op@error{Number name `#1' is undefined}% {See documentation about number name}% @@ -545,30 +546,30 @@ \else \edef\op@name{#2}% \op@length - \count@i=\@nameuse{OP@\op@name @w}\relax + \op@count@i=\@nameuse{OP@\op@name @w}\relax \edef\op@arg{\op@arg.}% \let\next\op@@split \fi - \expandafter\next\op@arg\@nil + \expandafter\next\op@arg\op@nil \endgroup } -\def\op@@split#1#2\@nil{% - \ifnum\count@i>0 +\def\op@@split#1#2\op@nil{% + \ifnum\op@count@i>0 \edef\op@argi{#1}% \edef\op@argii{#2}% \let\next\op@@split \expandafter\op@testchar\op@argi \ifop@isdigit - \@namexdef{OP@\op@name @\the\count@i}{\op@argi}% - \advance\count@i by -1 + \@namexdef{OP@\op@name @\the\op@count@i}{\op@argi}% + \advance\op@count@i by -1 \fi \else \let\next\relax \let\op@argii\relax \fi - \expandafter\next\op@argii\@nil + \expandafter\next\op@argii\op@nil } -\def\op@readnumber#1#2\@nil{% +\def\op@readnumber#1#2\op@nil{% \op@testchar{#1}% \ifop@isdigit \else \ifop@isplus \else @@ -581,25 +582,25 @@ } \def\op@length{% \begingroup - \expandafter\op@@length\op@arg\@nil - \ifnum\count@i=0 - \count@i=1 + \expandafter\op@@length\op@arg\op@nil + \ifnum\op@count@i=0 + \op@count@i=1 \xdef\op@arg{0\op@arg}% \fi - \@namexdef{OP@\op@name @i}{\the\count@i}% - \@namexdef{OP@\op@name @d}{\the\count@ii}% - \advance\count@i by \count@ii - \@namexdef{OP@\op@name @w}{\the\count@i}% + \@namexdef{OP@\op@name @i}{\the\op@count@i}% + \@namexdef{OP@\op@name @d}{\the\op@count@ii}% + \advance\op@count@i by \op@count@ii + \@namexdef{OP@\op@name @w}{\the\op@count@i}% \endgroup } -\def\op@@length#1#2\@nil{% +\def\op@@length#1#2\op@nil{% \edef\op@argi{#1}% \edef\op@argii{#2}% \expandafter\op@testchar\op@argi \ifop@isdigit \@namexdef{OP@\op@name @s}{0}% - \count@i=1 - \count@ii=0 + \op@count@i=1 + \op@count@ii=0 \ifx\empty\op@argii \let\next\relax \let\op@argii\relax @@ -614,8 +615,8 @@ \let\next\op@length@after@sign \else \ifop@isdecimalsep \@namexdef{OP@\op@name @s}{0}% - \count@i=0 - \count@ii=0 + \op@count@i=0 + \op@count@ii=0 \let\next\op@length@after@decimalsep \else \op@error{\op@argi\op@argii\space isn't a valid number}% @@ -629,14 +630,14 @@ \let\next\relax \let\op@argii\relax \fi - \expandafter\next\op@argii\@nil + \expandafter\next\op@argii\op@nil } -\def\op@length@after@digit#1#2\@nil{% +\def\op@length@after@digit#1#2\op@nil{% \edef\op@argi{#1}% \edef\op@argii{#2}% \expandafter\op@testchar\op@argi \ifop@isdigit - \advance\count@i by 1 + \advance\op@count@i by 1 \let\next\op@length@after@digit \else \ifop@isdecimalsep \let\next\op@length@after@decimalsep @@ -650,9 +651,9 @@ \ifx\empty\op@argii \let\next\relax \fi - \expandafter\next\op@argii\@nil + \expandafter\next\op@argii\op@nil } -\def\op@length@after@sign#1#2\@nil{% +\def\op@length@after@sign#1#2\op@nil{% \edef\op@argi{#1}% \edef\op@argii{#2}% \expandafter\op@testchar\op@argi @@ -671,27 +672,27 @@ {See documentation for syntax of valid number}% \let\next\relax \else - \count@i=0 - \count@ii=0 + \op@count@i=0 + \op@count@ii=0 \let\next\op@length@after@decimalsep \fi \else \ifop@isdigit - \count@i=1 - \count@ii=0 + \op@count@i=1 + \op@count@ii=0 \ifx\empty\op@argii \let\next\relax \else \let\next\op@length@after@digit \fi \fi\fi\fi\fi - \expandafter\next\op@argii\@nil + \expandafter\next\op@argii\op@nil } -\def\op@length@after@decimalsep#1#2\@nil{% +\def\op@length@after@decimalsep#1#2\op@nil{% \edef\op@argi{#1}% \edef\op@argii{#2}% \expandafter\op@testchar\op@argi \ifop@isdigit - \advance\count@ii by 1 + \advance\op@count@ii by 1 \let\next\op@length@after@decimalsep \else \op@error{#1#2 not allowed here. \space I forget it}% @@ -704,7 +705,7 @@ \let\next\relax \let\op@argii\relax \fi - \expandafter\next\op@argii\@nil + \expandafter\next\op@argii\op@nil } \def\op@unsplit#1#2{% \begingroup @@ -714,22 +715,22 @@ \else \def\op@macroname{}% \fi - \count@z=\@nameuse{OP@\op@name @i}\relax - \count@i=\@nameuse{OP@\op@name @w}\relax + \op@count@z=\@nameuse{OP@\op@name @i}\relax + \op@count@i=\@nameuse{OP@\op@name @w}\relax \loop - \ifnum\count@z>0 + \ifnum\op@count@z>0 \edef\op@macroname{\op@macroname - \@nameuse{OP@\op@name @\the\count@i}}% - \advance\count@z by-1 - \advance\count@i by-1 + \@nameuse{OP@\op@name @\the\op@count@i}}% + \advance\op@count@z by-1 + \advance\op@count@i by-1 \repeat - \ifnum\count@i>0 + \ifnum\op@count@i>0 \edef\op@macroname{\op@macroname\op@decimalsepsymbol}% \loop - \ifnum\count@i>0 + \ifnum\op@count@i>0 \edef\op@macroname{\op@macroname - \@nameuse{OP@\op@name @\the\count@i}}% - \advance\count@i by-1 + \@nameuse{OP@\op@name @\the\op@count@i}}% + \advance\op@count@i by-1 \repeat \fi \@namexdef{Op@#2}{\op@macroname}% @@ -762,55 +763,55 @@ \begingroup \edef\op@name{#4}% \dimen0=\opcolumnwidth - \count@z=#1% - \advance\count@z by-\@nameuse{OP@\op@name @i}\relax - \multiply\dimen0 by\count@z + \op@count@z=#1% + \advance\op@count@z by-\@nameuse{OP@\op@name @i}\relax + \multiply\dimen0 by\op@count@z \global\setbox0=\hbox{% \op@strut\vrule width\dimen0 height\z@ depth\z@}% - \count@z=\@nameuse{OP@\op@name @i}\relax - \count@i=\@nameuse{OP@\op@name @w}\relax + \op@count@z=\@nameuse{OP@\op@name @i}\relax + \op@count@i=\@nameuse{OP@\op@name @w}\relax \loop - \ifnum\count@z>0 - \op@setstyle{#3.\the\count@z}% + \ifnum\op@count@z>0 + \op@setstyle{#3.\the\op@count@z}% \global\setbox0=\hbox{\box0 \hbox to\opcolumnwidth{\hss\the\op@currentstyle - {\@nameuse{OP@\op@name @\the\count@i}}\hss}}% - \advance\count@z by-1 - \advance\count@i by-1 + {\@nameuse{OP@\op@name @\the\op@count@i}}\hss}}% + \advance\op@count@z by-1 + \advance\op@count@i by-1 \repeat - \ifnum\count@i>0 + \ifnum\op@count@i>0 \op@setstyle{#3.d}% \global\setbox0=\hbox{\box0 \hbox to\op@decimalsepwidth{\hss \vrule width\op@decimalsepoffset height\z@ depth\z@ \the\op@currentstyle\op@decimalsepsymbol \hss}}% - \count@z=-1 + \op@count@z=-1 \loop - \ifnum\count@i>0 - \op@setstyle{#3.\the\count@z}% + \ifnum\op@count@i>0 + \op@setstyle{#3.\the\op@count@z}% \global\setbox0=\hbox{\box0 \hbox to\opcolumnwidth{\hss\the\op@currentstyle - {\@nameuse{OP@\op@name @\the\count@i}}\hss}}% - \advance\count@z by-1 - \advance\count@i by-1 + {\@nameuse{OP@\op@name @\the\op@count@i}}\hss}}% + \advance\op@count@z by-1 + \advance\op@count@i by-1 \repeat \fi \dimen0=\opcolumnwidth - \count@z=#2\relax - \advance\count@z by-\@nameuse{OP@\op@name @d}\relax - \multiply\dimen0 by\count@z + \op@count@z=#2\relax + \advance\op@count@z by-\@nameuse{OP@\op@name @d}\relax + \multiply\dimen0 by\op@count@z \global\setbox0=\hbox{\box0 \vrule width\dimen0 height\z@ depth\z@}% \endgroup } \def\op@setstyle#1{% \edef\op@arg{#1}% - \expandafter\op@@setstyle\op@arg..\@nil + \expandafter\op@@setstyle\op@arg..\op@nil } -\def\op@@setstyle#1.#2.#3\@nil{% +\def\op@@setstyle#1.#2.#3\op@nil{% \edef\op@styleroot{#1}% \edef\op@styleindex{#2}% - \op@setstylesubindex#3.\@nil + \op@setstylesubindex#3.\op@nil \ifx\empty\op@stylesubindex \@ifundefined{op@\op@styleroot.\op@styleindex}% {\op@currentstyle={\@nameuse{op@\op@styleroot.0}}}% @@ -825,7 +826,7 @@ {\@nameuse{op@\op@styleroot.\op@styleindex.\op@stylesubindex}}}% \fi } -\def\op@setstylesubindex#1.#2\@nil{\def\op@stylesubindex{#1}} +\def\op@setstylesubindex#1.#2\op@nil{\def\op@stylesubindex{#1}} \def\opdisplay{\@ifnextchar[{\op@displaypar}{\op@displaypar[nil]}} \def\op@displaypar[#1]#2#3{% \begingroup @@ -853,46 +854,78 @@ } \def\op@format#1#2#3{% \begingroup - \count@iii=#1\relax - \count@iv=#2\relax - \count@z=\count@iv - \advance\count@z by-\@nameuse{OP@#3@d}\relax - \ifnum\count@z>0 - \count@i=\@nameuse{OP@#3@w}\relax - \advance\count@z by\count@i\relax + \op@count@iii=#1\relax + \op@count@iv=#2\relax + \op@count@z=\op@count@iv + \advance\op@count@z by-\@nameuse{OP@#3@d}\relax + \ifnum\op@count@z>0 + \op@count@i=\@nameuse{OP@#3@w}\relax + \advance\op@count@z by\op@count@i\relax \loop - \@namexdef{OP@#3@\the\count@z}{\@nameuse{OP@#3@\the\count@i}}% - \advance\count@i by-1 - \advance\count@z by-1\relax - \ifnum\count@i>0 + \@namexdef{OP@#3@\the\op@count@z}{\@nameuse{OP@#3@\the\op@count@i}}% + \advance\op@count@i by-1 + \advance\op@count@z by-1\relax + \ifnum\op@count@i>0 \repeat \loop - \@namexdef{OP@#3@\the\count@z}{0}% - \advance\count@z by-1\relax - \ifnum\count@z>0 + \@namexdef{OP@#3@\the\op@count@z}{0}% + \advance\op@count@z by-1\relax + \ifnum\op@count@z>0 \repeat - \@namexdef{OP@#3@d}{\the\count@iv}% - \count@i=\@nameuse{OP@#3@i}% - \advance\count@i by\count@iv\relax - \@namexdef{OP@#3@w}{\the\count@i}% - \fi - \count@z=\count@iii - \advance\count@z by-\@nameuse{OP@#3@i}\relax - \ifnum\count@z>0 - \count@i=\@nameuse{OP@#3@w}\relax + \@namexdef{OP@#3@d}{\the\op@count@iv}% + \op@count@i=\@nameuse{OP@#3@i}% + \advance\op@count@i by\op@count@iv\relax + \@namexdef{OP@#3@w}{\the\op@count@i}% + \fi + \op@count@z=\op@count@iii + \advance\op@count@z by-\@nameuse{OP@#3@i}\relax + \ifnum\op@count@z>0 + \op@count@i=\@nameuse{OP@#3@w}\relax \loop - \advance\count@i by1 - \@namexdef{OP@#3@\the\count@i}{0}% - \advance\count@z by-1\relax - \ifnum\count@z>0 + \advance\op@count@i by1 + \@namexdef{OP@#3@\the\op@count@i}{0}% + \advance\op@count@z by-1\relax + \ifnum\op@count@z>0 \repeat - \@namexdef{OP@#3@i}{\the\count@iii}% + \@namexdef{OP@#3@i}{\the\op@count@iii}% \fi - \count@i=\@nameuse{OP@#3@i}\relax - \advance\count@i by\@nameuse{OP@#3@d}\relax - \@namexdef{OP@#3@w}{\the\count@i}% + \op@count@i=\@nameuse{OP@#3@i}\relax + \advance\op@count@i by\@nameuse{OP@#3@d}\relax + \@namexdef{OP@#3@w}{\the\op@count@i}% \endgroup } +% add 0.23 +\def\opexport{\@ifnextchar[{\op@export}{\op@export[nil]}} +\def\op@export[#1]#2#3{% + \begingroup + \def\op@@export{}% + \opset{#1}% + \expandafter\def\expandafter\op@decimalsepsymbol\op@decimalsepsymbol + \op@split{#2}{tmp}% + \ifop@error + \op@errorwrite + \else + \op@count@vi=0 + \loop + \ifnum\op@count@vi<\OP@tmp@d + \advance\op@count@vi by1 + \xdef\op@@export{\@nameuse{OP@tmp@\the\op@count@vi}\op@@export}% + \repeat + \ifnum\OP@tmp@d>0 + \xdef\op@@export{\op@decimalsepsymbol\op@@export}% + \op@count@i=0 + \loop + \ifnum\op@count@i<\OP@tmp@i + \advance\op@count@vi by1 + \advance\op@count@i by1 + \xdef\op@@export{\@nameuse{OP@tmp@\the\op@count@vi}\op@@export}% + \repeat + \fi + \fi + \endgroup + \edef#3{\op@@export}% +} +% end add 0.23 \def\opunzero#1{% \op@split{#1}{uzr}% \ifop@error @@ -904,47 +937,47 @@ } \def\op@unzero#1{% \begingroup - \count@z=\@nameuse{OP@#1@i}\relax - \count@i=\@nameuse{OP@#1@w}\relax - \count@ii=\@nameuse{OP@#1@i}\relax + \op@count@z=\@nameuse{OP@#1@i}\relax + \op@count@i=\@nameuse{OP@#1@w}\relax + \op@count@ii=\@nameuse{OP@#1@i}\relax \loop - \ifnum\count@z>1\relax - \ifnum\@nameuse{OP@#1@\the\count@i}=0\relax - \advance\count@ii by-1 + \ifnum\op@count@z>1\relax + \ifnum\@nameuse{OP@#1@\the\op@count@i}=0\relax + \advance\op@count@ii by-1 \else - \count@z=0 + \op@count@z=0 \fi - \advance\count@z by-1 - \advance\count@i by-1 + \advance\op@count@z by-1 + \advance\op@count@i by-1 \repeat - \@namexdef{OP@#1@i}{\the\count@ii}% - \count@z=\@nameuse{OP@#1@d}\relax - \count@i=1\relax - \count@ii=0\relax + \@namexdef{OP@#1@i}{\the\op@count@ii}% + \op@count@z=\@nameuse{OP@#1@d}\relax + \op@count@i=1\relax + \op@count@ii=0\relax \loop - \ifnum\count@z>0\relax - \ifnum\@nameuse{OP@#1@\the\count@i}=0\relax - \advance\count@ii by1 - \advance\count@z by-1 - \advance\count@i by1 + \ifnum\op@count@z>0\relax + \ifnum\@nameuse{OP@#1@\the\op@count@i}=0\relax + \advance\op@count@ii by1 + \advance\op@count@z by-1 + \advance\op@count@i by1 \else - \count@z=0 + \op@count@z=0 \fi \repeat - \ifnum\count@ii>0\relax - \count@z=1\relax - \count@i=\@nameuse{OP@#1@w}\relax - \count2=\count@ii - \advance\count@ii by1 + \ifnum\op@count@ii>0\relax + \op@count@z=1\relax + \op@count@i=\@nameuse{OP@#1@w}\relax + \count@=\op@count@ii + \advance\op@count@ii by1 \loop - \@namexdef{OP@#1@\the\count@z}{\@nameuse{OP@#1@\the\count@ii}}% - \ifnum\count@ii<\count@i - \advance\count@z by1 - \advance\count@ii by1 + \@namexdef{OP@#1@\the\op@count@z}{\@nameuse{OP@#1@\the\op@count@ii}}% + \ifnum\op@count@ii<\op@count@i + \advance\op@count@z by1 + \advance\op@count@ii by1 \repeat - \count@ii=\@nameuse{OP@#1@d}% - \advance\count@ii by-\count2 - \@namexdef{OP@#1@d}{\the\count@ii}% + \op@count@ii=\@nameuse{OP@#1@d}% + \advance\op@count@ii by-\count@ + \@namexdef{OP@#1@d}{\the\op@count@ii}% \fi \ifnum\@nameuse{OP@#1@i}=1\relax \ifnum\@nameuse{OP@#1@d}=0\relax @@ -953,9 +986,9 @@ \fi \fi \fi - \count@i=\@nameuse{OP@#1@i}\relax - \advance\count@i by\@nameuse{OP@#1@d}\relax - \@namexdef{OP@#1@w}{\the\count@i}% + \op@count@i=\@nameuse{OP@#1@i}\relax + \advance\op@count@i by\@nameuse{OP@#1@d}\relax + \@namexdef{OP@#1@w}{\the\op@count@i}% \endgroup } \def\opcopy#1#2{% @@ -972,11 +1005,11 @@ \@namexdef{OP@#2@i}{\@nameuse{OP@#1@i}}% \@namexdef{OP@#2@d}{\@nameuse{OP@#1@d}}% \@namexdef{OP@#2@s}{\@nameuse{OP@#1@s}}% - \count@z=\@nameuse{OP@#2@w}\relax + \op@count@z=\@nameuse{OP@#2@w}\relax \loop - \ifnum\count@z>0 - \@namexdef{OP@#2@\the\count@z}{\@nameuse{OP@#1@\the\count@z}}% - \advance\count@z by-1 + \ifnum\op@count@z>0 + \@namexdef{OP@#2@\the\op@count@z}{\@nameuse{OP@#1@\the\op@count@z}}% + \advance\op@count@z by-1 \repeat \endgroup } @@ -1020,25 +1053,25 @@ \global\opneqtrue \else \op@againtrue - \count@i=\OP@ca@w\relax - \count@ii=\OP@cb@w\relax + \op@count@i=\OP@ca@w\relax + \op@count@ii=\OP@cb@w\relax \loop \ifop@again - \ifnum\@nameuse{OP@ca@\the\count@i}> - \@nameuse{OP@cb@\the\count@ii}\relax + \ifnum\@nameuse{OP@ca@\the\op@count@i}> + \@nameuse{OP@cb@\the\op@count@ii}\relax \op@againfalse \global\opgttrue \global\opgetrue \global\opneqtrue - \else \ifnum\@nameuse{OP@ca@\the\count@i}< - \@nameuse{OP@cb@\the\count@ii}\relax + \else \ifnum\@nameuse{OP@ca@\the\op@count@i}< + \@nameuse{OP@cb@\the\op@count@ii}\relax \op@againfalse \global\oplttrue \global\opletrue \global\opneqtrue - \else \ifnum\count@i=1\relax + \else \ifnum\op@count@i=1\relax \op@againfalse - \ifnum\count@ii=1\relax + \ifnum\op@count@ii=1\relax \global\opeqtrue \global\opgetrue \global\opletrue @@ -1047,14 +1080,14 @@ \global\opletrue \global\opneqtrue \fi - \else \ifnum\count@ii=1\relax + \else \ifnum\op@count@ii=1\relax \op@againfalse \global\opgttrue \global\opgetrue \global\opneqtrue \fi\fi\fi\fi - \advance\count@i by-1 - \advance\count@ii by-1 + \advance\op@count@i by-1 + \advance\op@count@ii by-1 \repeat \fi\fi \ifnum\OP@ca@s=1\relax @@ -1221,56 +1254,56 @@ \def\op@add#1#2#3{% \begingroup \global\op@carryfalse - \count@i=\op@max{\@nameuse{OP@#1@i}}{\@nameuse{OP@#2@i}}% - \count@ii=\op@max{\@nameuse{OP@#1@d}}{\@nameuse{OP@#2@d}}% - \op@format{\the\count@i}{\the\count@ii}{#1}% - \op@format{\the\count@i}{\the\count@ii}{#2}% - \@namexdef{OP@#3@i}{\the\count@i}% - \@namexdef{OP@#3@d}{\the\count@ii}% + \op@count@i=\op@max{\@nameuse{OP@#1@i}}{\@nameuse{OP@#2@i}}% + \op@count@ii=\op@max{\@nameuse{OP@#1@d}}{\@nameuse{OP@#2@d}}% + \op@format{\the\op@count@i}{\the\op@count@ii}{#1}% + \op@format{\the\op@count@i}{\the\op@count@ii}{#2}% + \@namexdef{OP@#3@i}{\the\op@count@i}% + \@namexdef{OP@#3@d}{\the\op@count@ii}% \@namexdef{OP@#3@s}{0}% \xdef\OP@carry@s{0}% \xdef\OP@carry@d{0}% - \advance\count@i by\count@ii - \@namexdef{OP@#3@w}{\the\count@i}% - \xdef\OP@carry@i{\the\count@i}% - \xdef\OP@carry@w{\the\count@i}% - \count@ii=1 + \advance\op@count@i by\op@count@ii + \@namexdef{OP@#3@w}{\the\op@count@i}% + \xdef\OP@carry@i{\the\op@count@i}% + \xdef\OP@carry@w{\the\op@count@i}% + \op@count@ii=1 \def\op@carry{0}% \@namexdef{OP@carry@1}{ }% \loop - \count@z=\@nameuse{OP@#1@\the\count@ii}% - \advance\count@z by\@nameuse{OP@#2@\the\count@ii}% - \advance\count@z by\op@carry\relax - \ifnum\count@z>9 - \advance\count@z by-10 + \op@count@z=\@nameuse{OP@#1@\the\op@count@ii}% + \advance\op@count@z by\@nameuse{OP@#2@\the\op@count@ii}% + \advance\op@count@z by\op@carry\relax + \ifnum\op@count@z>9 + \advance\op@count@z by-10 \def\op@carry{1}% \global\op@carrytrue \else \def\op@carry{0}% \fi - \@namexdef{OP@#3@\the\count@ii}{\the\count@z}% - \ifnum\count@ii<\count@i - \advance\count@ii by1\relax + \@namexdef{OP@#3@\the\op@count@ii}{\the\op@count@z}% + \ifnum\op@count@ii<\op@count@i + \advance\op@count@ii by1\relax \ifnum\op@carry=0 - \@namexdef{OP@carry@\the\count@ii}{ }% + \@namexdef{OP@carry@\the\op@count@ii}{ }% \else - \@namexdef{OP@carry@\the\count@ii}{1}% + \@namexdef{OP@carry@\the\op@count@ii}{1}% \global\op@carrytrue \fi \repeat \ifnum\op@carry=1 - \advance\count@i by1 - \@namexdef{OP@#3@w}{\the\count@i}% - \@namexdef{OP@#3@\the\count@i}{1}% + \advance\op@count@i by1 + \@namexdef{OP@#3@w}{\the\op@count@i}% + \@namexdef{OP@#3@\the\op@count@i}{1}% \ifop@lastcarry - \@namexdef{OP@carry@w}{\the\count@i}% - \@namexdef{OP@carry@i}{\the\count@i}% - \@namexdef{OP@carry@\the\count@i}{1}% + \@namexdef{OP@carry@w}{\the\op@count@i}% + \@namexdef{OP@carry@i}{\the\op@count@i}% + \@namexdef{OP@carry@\the\op@count@i}{1}% \global\op@carrytrue \fi - \count@i=\@nameuse{OP@#3@i}\relax - \advance\count@i by1 - \@namexdef{OP@#3@i}{\the\count@i}% + \op@count@i=\@nameuse{OP@#3@i}\relax + \advance\op@count@i by1 + \@namexdef{OP@#3@i}{\the\op@count@i}% \fi \endgroup } @@ -1376,45 +1409,45 @@ \def\op@sub#1#2#3{% \begingroup \global\op@carryfalse - \count@i=\op@max{\@nameuse{OP@#1@i}}{\@nameuse{OP@#2@i}}\relax - \count@ii=\op@max{\@nameuse{OP@#1@d}}{\@nameuse{OP@#2@d}}\relax - \count@iii=\@nameuse{OP@#2@w}\relax - \advance\count@iii by1 - \op@format{\the\count@i}{\the\count@ii}{#1}% - \op@format{\the\count@i}{\the\count@ii}{#2}% - \@namexdef{OP@#3@i}{\the\count@i}% - \@namexdef{OP@#3@d}{\the\count@ii}% + \op@count@i=\op@max{\@nameuse{OP@#1@i}}{\@nameuse{OP@#2@i}}\relax + \op@count@ii=\op@max{\@nameuse{OP@#1@d}}{\@nameuse{OP@#2@d}}\relax + \op@count@iii=\@nameuse{OP@#2@w}\relax + \advance\op@count@iii by1 + \op@format{\the\op@count@i}{\the\op@count@ii}{#1}% + \op@format{\the\op@count@i}{\the\op@count@ii}{#2}% + \@namexdef{OP@#3@i}{\the\op@count@i}% + \@namexdef{OP@#3@d}{\the\op@count@ii}% \@namexdef{OP@#3@s}{0}% \xdef\OP@carry@s{0}% \xdef\OP@carry@d{0}% - \advance\count@i by\count@ii - \@namexdef{OP@#3@w}{\the\count@i}% - \xdef\OP@carry@i{\the\count@i}% - \xdef\OP@carry@w{\the\count@i}% - \count@ii=1 + \advance\op@count@i by\op@count@ii + \@namexdef{OP@#3@w}{\the\op@count@i}% + \xdef\OP@carry@i{\the\op@count@i}% + \xdef\OP@carry@w{\the\op@count@i}% + \op@count@ii=1 \def\op@carry{0}% \@namexdef{OP@carry@1}{ }% \loop - \count@z=\@nameuse{OP@#1@\the\count@ii}% - \advance\count@z by-\@nameuse{OP@#2@\the\count@ii}% - \advance\count@z by-\op@carry\relax - \ifnum\count@z<0 - \advance\count@z by10 + \op@count@z=\@nameuse{OP@#1@\the\op@count@ii}% + \advance\op@count@z by-\@nameuse{OP@#2@\the\op@count@ii}% + \advance\op@count@z by-\op@carry\relax + \ifnum\op@count@z<0 + \advance\op@count@z by10 \def\op@carry{1}% \else \def\op@carry{0}% \fi - \@namexdef{OP@#3@\the\count@ii}{\the\count@z}% - \ifnum\count@ii<\count@i - \advance\count@ii by1\relax - \@namexdef{OP@carry@\the\count@ii}{ }% + \@namexdef{OP@#3@\the\op@count@ii}{\the\op@count@z}% + \ifnum\op@count@ii<\op@count@i + \advance\op@count@ii by1\relax + \@namexdef{OP@carry@\the\op@count@ii}{ }% \ifnum\op@carry=0 \else \ifop@lastcarry - \@namexdef{OP@carry@\the\count@ii}{1}% + \@namexdef{OP@carry@\the\op@count@ii}{1}% \global\op@carrytrue \else - \ifnum\count@ii<\count@iii\relax - \@namexdef{OP@carry@\the\count@ii}{1}% + \ifnum\op@count@ii<\op@count@iii\relax + \@namexdef{OP@carry@\the\op@count@ii}{1}% \global\op@carrytrue \fi \fi @@ -1434,14 +1467,14 @@ \op@format{\OP@a@i}{\OP@b@d}{a}% \fi \fi - \count@i=\op@max{\OP@a@i}{\OP@b@i}% - \count@i=\op@max{\the\count@i}{\OP@r@i}% - \advance\count@i by1 - \count@ii=\op@max{\OP@a@d}{\OP@b@d}% - \count@ii=\op@max{\the\count@ii}{\OP@r@d}% - \count@z=\count@i - \advance\count@z by\count@ii - \setbox1=\hbox to\count@z\opcolumnwidth{% + \op@count@i=\op@max{\OP@a@i}{\OP@b@i}% + \op@count@i=\op@max{\the\op@count@i}{\OP@r@i}% + \advance\op@count@i by1 + \op@count@ii=\op@max{\OP@a@d}{\OP@b@d}% + \op@count@ii=\op@max{\the\op@count@ii}{\OP@r@d}% + \op@count@z=\op@count@i + \advance\op@count@z by\op@count@ii + \setbox1=\hbox to\op@count@z\opcolumnwidth{% \ifx\op@voperator\op@string@top \oplput(0,2){\op@realsymbol}% \else\ifx\op@voperator\op@string@bottom @@ -1449,16 +1482,16 @@ \else \oplput(0,1.5){\op@realsymbol}% \fi\fi - \ophline(0,0.75){\the\count@z}% + \ophline(0,0.75){\the\op@count@z}% \ifnum\OP@r@d>0\relax - \oplput(\the\count@z,0.75){% + \oplput(\the\op@count@z,0.75){% \vrule width\op@decimalsepwidth depth0.5\op@hrulewidth height0.5\op@hrulewidth} \fi \ifx\op@realsymbol\op@subsymbol \ifop@carrysub \ifop@carry - \op@makebox{\the\count@z}{0}{carrystyle}{carry}% + \op@makebox{\the\op@count@z}{0}{carrystyle}{carry}% \oplput(\op@offsetcarry,2){\kern\opcolumnwidth\copy0}% \oplput(\op@offsetcarry,1){\box0}% \fi @@ -1468,16 +1501,16 @@ \ifx\op@realsymbol\op@addsymbol \ifop@carryadd \ifop@carry - \op@makebox{\the\count@z}{0}{carrystyle}{carry}% + \op@makebox{\the\op@count@z}{0}{carrystyle}{carry}% \hbox{\box0}% \fi \fi \fi - \op@makebox{\the\count@i}{\the\count@ii}{operandstyle.1}{a}% + \op@makebox{\the\op@count@i}{\the\op@count@ii}{operandstyle.1}{a}% \hbox{\box0}% - \op@makebox{\the\count@i}{\the\count@ii}{operandstyle.2}{b}% + \op@makebox{\the\op@count@i}{\the\op@count@ii}{operandstyle.2}{b}% \hbox{\box0}% - \op@makebox{\the\count@i}{\the\count@ii}{resultstyle}{r}% + \op@makebox{\the\op@count@i}{\the\op@count@ii}{resultstyle}{r}% \hbox{\box0}% }% }% @@ -1562,31 +1595,31 @@ \expandafter\if\csname OP@b@\OP@b@w\endcsname0 \ifnum\OP@r@i>1 \expandafter\if\csname OP@r@\OP@r@w\endcsname0 - \count@i=\OP@r@w - \advance\count@i\m@ne - \edef\OP@r@w{\the\count@i}% - \count@i=\OP@r@i - \advance\count@i\m@ne - \edef\OP@r@i{\the\count@i}% + \op@count@i=\OP@r@w + \advance\op@count@i\m@ne + \edef\OP@r@w{\the\op@count@i}% + \op@count@i=\OP@r@i + \advance\op@count@i\m@ne + \edef\OP@r@i{\the\op@count@i}% \fi\fi\fi\fi \setbox1=\hbox to\OP@r@w\opcolumnwidth{% \vbox{% \ifx\op@hfactor\op@string@right - \count@i=\OP@r@w - \advance\count@i by-\OP@a@d - \op@makebox{\the\count@i}{\OP@a@d}{operandstyle.1}{a}% + \op@count@i=\OP@r@w + \advance\op@count@i by-\OP@a@d + \op@makebox{\the\op@count@i}{\OP@a@d}{operandstyle.1}{a}% \hbox{\box0}% - \count@i=\OP@r@w - \advance\count@i by-\OP@b@d - \op@makebox{\the\count@i}{\OP@b@d}{operandstyle.2}{b}% + \op@count@i=\OP@r@w + \advance\op@count@i by-\OP@b@d + \op@makebox{\the\op@count@i}{\OP@b@d}{operandstyle.2}{b}% \hbox{\box0}% \else - \count@i=\OP@r@w - \count@ii=\op@max{\OP@a@d}{\OP@b@d}% - \advance\count@i by-\count@ii - \op@makebox{\the\count@i}{\the\count@ii}{operandstyle.1}{a}% + \op@count@i=\OP@r@w + \op@count@ii=\op@max{\OP@a@d}{\OP@b@d}% + \advance\op@count@i by-\op@count@ii + \op@makebox{\the\op@count@i}{\the\op@count@ii}{operandstyle.1}{a}% \hbox{\box0}% - \op@makebox{\the\count@i}{\the\count@ii}{operandstyle.2}{b}% + \op@makebox{\the\op@count@i}{\the\op@count@ii}{operandstyle.2}{b}% \hbox{\box0}% \fi \op@againtrue @@ -1595,31 +1628,31 @@ \op@againfalse \fi \fi - \global\count@z=0\relax + \global\op@count@z=0\relax \ifop@again - \count@ii=0\relax + \op@count@ii=0\relax \setbox2=\hbox{}% \loop - \ifnum\count@ii<\OP@b@w - \advance\count@ii by1 - \count@iii=\@nameuse{OP@b@\the\count@ii}% - \count@iv=\OP@r@w - \advance\count@iv by-\count@ii - \advance\count@iv by1 - \op@makebox{\the\count@iv}{0}% - {intermediarystyle.\the\count@ii}{T\the\count@iii}% + \ifnum\op@count@ii<\OP@b@w + \advance\op@count@ii by1 + \op@count@iii=\@nameuse{OP@b@\the\op@count@ii}% + \op@count@iv=\OP@r@w + \advance\op@count@iv by-\op@count@ii + \advance\op@count@iv by1 + \op@makebox{\the\op@count@iv}{0}% + {intermediarystyle.\the\op@count@ii}{T\the\op@count@iii}% \ifx\op@displayintermediary\op@string@all \hbox{\box0\copy2}% - \global\advance\count@z by1 + \global\advance\op@count@z by1 \else - \ifnum\the\count@iii=0 + \ifnum\the\op@count@iii=0 \ifx\op@displayshiftintermediary\op@string@shift \setbox2=\hbox{\box2\hbox to\opcolumnwidth{% \hss\op@shiftintermediarysymbol\hss}}% \fi \else \hbox{\box0\copy2}% - \global\advance\count@z by1 + \global\advance\op@count@z by1 \ifx\op@displayshiftintermediary\op@string@shift \setbox2=\hbox{}% \fi @@ -1634,46 +1667,46 @@ \op@makebox{\OP@r@i}{\OP@r@d}{resultstyle}{r}% \hbox{\box0}% }% - \count@i=\OP@r@w - \ophline(-\the\count@i,0.75){\the\count@i}% + \op@count@i=\OP@r@w + \ophline(-\the\op@count@i,0.75){\the\op@count@i}% \ifnum\OP@r@d>0\relax - \oprput(-\the\count@i,0.75){% + \oprput(-\the\op@count@i,0.75){% \vrule width\op@decimalsepwidth depth0.5\op@hrulewidth height0.5\op@hrulewidth} \fi \ifx\op@hfactor\op@string@right - \count@i=\op@max{\OP@a@w}{\OP@b@w}% + \op@count@i=\op@max{\OP@a@w}{\OP@b@w}% \else - \count@i=\op@max{\OP@a@d}{\OP@b@d}% - \advance\count@i by\op@max{\OP@a@i}{\OP@b@i}% + \op@count@i=\op@max{\OP@a@d}{\OP@b@d}% + \advance\op@count@i by\op@max{\OP@a@i}{\OP@b@i}% \fi - \advance\count@i by1\relax - \ophline(-\the\count@i,\the\count@z.75){\the\count@i}% + \advance\op@count@i by1\relax + \ophline(-\the\op@count@i,\the\op@count@z.75){\the\op@count@i}% \ifx\op@voperator\op@string@top - \advance\count@z by2 - \oplput(-\the\count@i,\the\count@z){\op@mulsymbol}% - \advance\count@z by-2 + \advance\op@count@z by2 + \oplput(-\the\op@count@i,\the\op@count@z){\op@mulsymbol}% + \advance\op@count@z by-2 \else\ifx\op@voperator\op@string@bottom - \advance\count@z by1 - \oplput(-\the\count@i,\the\count@z){\op@mulsymbol}% - \advance\count@z by-1 + \advance\op@count@z by1 + \oplput(-\the\op@count@i,\the\op@count@z){\op@mulsymbol}% + \advance\op@count@z by-1 \else - \advance\count@z by1 - \oplput(-\the\count@i,\the\count@z.5){\op@mulsymbol}% - \advance\count@z by-1 + \advance\op@count@z by1 + \oplput(-\the\op@count@i,\the\op@count@z.5){\op@mulsymbol}% + \advance\op@count@z by-1 \fi\fi }% \leavevmode \ifx\op@voperation\op@string@center - \advance\count@z by3 + \advance\op@count@z by3 \dimen0=\oplineheight - \multiply\dimen0 by\count@z + \multiply\dimen0 by\op@count@z \dimen0=0.5\dimen0 \lower\dimen0\box1 \else\ifx\op@voperation\op@string@top - \advance\count@z by2 + \advance\op@count@z by2 \dimen0=\oplineheight - \multiply\dimen0 by\count@z + \multiply\dimen0 by\op@count@z \lower\dimen0\box1 \else \box1 @@ -1684,33 +1717,33 @@ \def\op@mul#1#2#3{% \begingroup \op@multable{#1}% - \count@z=\@nameuse{OP@#2@w}\relax + \op@count@z=\@nameuse{OP@#2@w}\relax \op@copy{zero}{mr}% \loop - \count@iii=\@nameuse{OP@#2@\the\count@z}% - \advance\count@z by-1 - \op@copy{T\the\count@iii}{rr}% - \op@lshift{\the\count@z}{rr}% + \op@count@iii=\@nameuse{OP@#2@\the\op@count@z}% + \advance\op@count@z by-1 + \op@copy{T\the\op@count@iii}{rr}% + \op@lshift{\the\op@count@z}{rr}% \op@add{rr}{mr}{mr}% - \ifnum\count@z>0 + \ifnum\op@count@z>0 \repeat - \count@z=\@nameuse{OP@#1@d}% - \advance\count@z by\@nameuse{OP@#2@d}% - \xdef\OP@mr@d{\the\count@z}% - \count@i=\OP@mr@w - \advance\count@i by-\count@z - \ifnum\count@i>0\relax - \xdef\OP@mr@i{\the\count@i}% + \op@count@z=\@nameuse{OP@#1@d}% + \advance\op@count@z by\@nameuse{OP@#2@d}% + \xdef\OP@mr@d{\the\op@count@z}% + \op@count@i=\OP@mr@w + \advance\op@count@i by-\op@count@z + \ifnum\op@count@i>0\relax + \xdef\OP@mr@i{\the\op@count@i}% \else \xdef\OP@mr@i{1}% - \count@z=\@nameuse{OP@mr@d}% - \advance\count@z by1 - \count@i=\@nameuse{OP@mr@w}% - \@namexdef{OP@mr@w}{\the\count@z}% + \op@count@z=\@nameuse{OP@mr@d}% + \advance\op@count@z by1 + \op@count@i=\@nameuse{OP@mr@w}% + \@namexdef{OP@mr@w}{\the\op@count@z}% \loop - \ifnum\count@i<\count@z - \advance\count@i by1 - \@namexdef{OP@mr@\the\count@i}{0}% + \ifnum\op@count@i<\op@count@z + \advance\op@count@i by1 + \@namexdef{OP@mr@\the\op@count@i}{0}% \repeat \fi \op@copy{mr}{#3}% @@ -1721,6 +1754,7 @@ \@namexdef{OP@T1@i}{\@nameuse{OP@T1@w}}% \@namexdef{OP@T1@d}{0}% \@namexdef{OP@T1@s}{0}% + \op@unzero{T1}% \op@add{T1}{T1}{T2}% \op@add{T1}{T2}{T3}% \op@add{T1}{T3}{T4}% @@ -1729,46 +1763,45 @@ \op@add{T1}{T6}{T7}% \op@add{T1}{T7}{T8}% \op@add{T1}{T8}{T9}% - \op@unzero{T1}% \op@format{\@nameuse{OP@T1@i}}{\@nameuse{OP@T1@d}}{T0}% } \def\op@lshift#1#2{% \begingroup - \count@i=#1\relax - \count@z=\@nameuse{OP@#2@w}\relax - \advance\count@i by\count@z - \@namexdef{OP@#2@w}{\the\count@i}% - \@namexdef{OP@#2@i}{\the\count@i}% + \op@count@i=#1\relax + \op@count@z=\@nameuse{OP@#2@w}\relax + \advance\op@count@i by\op@count@z + \@namexdef{OP@#2@w}{\the\op@count@i}% + \@namexdef{OP@#2@i}{\the\op@count@i}% \loop - \ifnum\count@z>0 - \@namexdef{OP@#2@\the\count@i}{\@nameuse{OP@#2@\the\count@z}}% - \advance\count@z by-1 - \advance\count@i by-1 + \ifnum\op@count@z>0 + \@namexdef{OP@#2@\the\op@count@i}{\@nameuse{OP@#2@\the\op@count@z}}% + \advance\op@count@z by-1 + \advance\op@count@i by-1 \repeat \loop - \ifnum\count@i>0 - \@namexdef{OP@#2@\the\count@i}{0}% - \advance\count@i by-1 + \ifnum\op@count@i>0 + \@namexdef{OP@#2@\the\op@count@i}{0}% + \advance\op@count@i by-1 \repeat \endgroup } \def\op@rshift#1#2{% \begingroup - \count@i=#1\relax - \count@z=\@nameuse{OP@#2@w}\relax - \advance\count@z by-\count@i - \ifnum\count@z>0 - \@namexdef{OP@#2@w}{\the\count@z}% - \@namexdef{OP@#2@i}{\the\count@z}% + \op@count@i=#1\relax + \op@count@z=\@nameuse{OP@#2@w}\relax + \advance\op@count@z by-\op@count@i + \ifnum\op@count@z>0 + \@namexdef{OP@#2@w}{\the\op@count@z}% + \@namexdef{OP@#2@i}{\the\op@count@z}% \@namexdef{OP@#2@d}{0}% \@namexdef{OP@#2@s}{0}% - \advance\count@i by1\relax - \count@ii=1 + \advance\op@count@i by1\relax + \op@count@ii=1 \loop - \@namexdef{OP@#2@\the\count@ii}{\@nameuse{OP@#2@\the\count@i}}% - \advance\count@i by1 - \ifnum\count@ii<\count@z - \advance\count@ii by1 + \@namexdef{OP@#2@\the\op@count@ii}{\@nameuse{OP@#2@\the\op@count@i}}% + \advance\op@count@i by1 + \ifnum\op@count@ii<\op@count@z + \advance\op@count@ii by1 \repeat \else \op@copy{zero}{#2}% @@ -1782,6 +1815,16 @@ \opset{#1} \op@split{#2}{a}% \op@split{#3}{b}% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% Ajout du 20/11/2006 %%% +%%% Sur indication de Cristophe Poulain %%% + \op@cmp{b}{zero}% + \ifopeq + \op@error{divisor must be nonzero}% + {You have to learn some math}% + \fi +%%% Fin ajout %%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \ifop@error \op@errorwrite \else @@ -1825,6 +1868,16 @@ \opset{#1}% \op@split{#2}{a}% \op@split{#3}{b}% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% Ajout du 20/11/2006 %%% +%%% Sur indication de Cristophe Poulain %%% + \op@cmp{b}{zero}% + \ifopeq + \op@error{divisor must be nonzero}% + {You have to learn some math}% + \fi +%%% Fin ajout %%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \ifop@error \op@errorwrite \else @@ -1862,35 +1915,35 @@ \op@unzero{b}% \ifx\op@shiftdecimalsep\op@string@none \def\op@shift{0}% - \count@v=\OP@a@d - \advance\count@v by-\OP@b@d\relax - \ifnum\count@v>0 - \op@divpowerten{qq}{\the\count@v}% + \op@count@v=\OP@a@d + \advance\op@count@v by-\OP@b@d\relax + \ifnum\op@count@v>0 + \op@divpowerten{qq}{\the\op@count@v}% \else - \count@v=-\count@v - \op@mulpowerten{qq}{\the\count@v}% + \op@count@v=-\op@count@v + \op@mulpowerten{qq}{\the\op@count@v}% \fi \else\ifx\op@shiftdecimalsep\op@string@divisor \edef\op@shift{\OP@a@d}% - \count@v=\OP@a@d - \advance\count@v by-\OP@b@d\relax - \ifnum\count@v>0 - \op@divpowerten{qq}{\the\count@v}% + \op@count@v=\OP@a@d + \advance\op@count@v by-\OP@b@d\relax + \ifnum\op@count@v>0 + \op@divpowerten{qq}{\the\op@count@v}% \else - \count@v=-\count@v - \op@mulpowerten{qq}{\the\count@v}% + \op@count@v=-\op@count@v + \op@mulpowerten{qq}{\the\op@count@v}% \fi \edef\op@shift{\OP@b@d}% \op@split{#2}{a}% \ifx\op@strikedecimalsepsymbol\empty \op@unzero{a}% \else - \count@z=\OP@a@w + \op@count@z=\OP@a@w \fi \op@mulpowerten{a}{\OP@b@d}% \ifx\op@strikedecimalsepsymbol\empty\else - \advance\count@z by-\OP@a@d - \op@format{\the\count@z}{\OP@a@d}{a}% + \advance\op@count@z by-\OP@a@d + \op@format{\the\op@count@z}{\OP@a@d}{a}% \fi \xdef\OP@b@i{\OP@b@w}% \xdef\OP@b@d{0}% @@ -1903,16 +1956,16 @@ \op@unzero{a}% \op@unzero{b}% \else - \count@z=\OP@a@w - \count@i=\OP@b@w + \op@count@z=\OP@a@w + \op@count@i=\OP@b@w \fi \op@mulpowerten{a}{\op@shift}% \op@mulpowerten{b}{\op@shift}% \ifx\op@strikedecimalsepsymbol\empty\else - \advance\count@z by-\OP@a@d - \op@format{\the\count@z}{\OP@a@d}{a}% - \advance\count@i by-\OP@b@d - \op@format{\the\count@i}{\OP@b@d}{b}% + \advance\op@count@z by-\OP@a@d + \op@format{\the\op@count@z}{\OP@a@d}{a}% + \advance\op@count@i by-\OP@b@d + \op@format{\the\op@count@i}{\OP@b@d}{b}% \fi \fi\fi \ifx\op@country\op@string@french @@ -1999,6 +2052,16 @@ \begingroup \op@split{#1}{a}% \op@split{#2}{b}% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% Ajout du 20/11/2006 %%% +%%% Sur indication de Cristophe Poulain %%% + \op@cmp{b}{zero}% + \ifopeq + \op@error{divisor must be nonzero}% + {You have to learn some math}% + \fi +%%% Fin ajout %%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \ifop@error \op@errorwrite \else @@ -2041,6 +2104,16 @@ \let\op@shiftdecimalsep\op@string@both \op@split{#2}{a}% \op@split{#3}{b}% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% Ajout du 20/11/2006 %%% +%%% Sur indication de Cristophe Poulain %%% + \op@cmp{b}{zero}% + \ifopeq + \op@error{divisor must be nonzero}% + {You have to learn some math}% + \fi +%%% Fin ajout %%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \ifop@error \op@errorwrite \else @@ -2062,16 +2135,16 @@ \op@copy{q}{qq}% \edef\op@shift{\op@max{\OP@a@d}{\OP@b@d}}% \ifx\op@strikedecimalsepsymbol\empty\else - \count@z=\OP@a@w - \count@i=\OP@b@w + \op@count@z=\OP@a@w + \op@count@i=\OP@b@w \fi \op@mulpowerten{a}{\op@shift}% \op@mulpowerten{b}{\op@shift}% \ifx\op@strikedecimalsepsymbol\empty\else - \advance\count@z by-\OP@a@d - \op@format{\the\count@z}{\OP@a@d}{a}% - \advance\count@i by-\OP@b@d - \op@format{\the\count@i}{\OP@b@d}{b}% + \advance\op@count@z by-\OP@a@d + \op@format{\the\op@count@z}{\OP@a@d}{a}% + \advance\op@count@i by-\OP@b@d + \op@format{\the\op@count@i}{\OP@b@d}{b}% \fi \ifx\op@country\op@string@french \op@divdisplayone @@ -2162,23 +2235,23 @@ } \def\op@divdisplayone{% \begingroup - \count@z=\z@\relax - \count@i=\OP@a@w + \op@count@z=\z@\relax + \op@count@i=\OP@a@w \loop - \ifnum\@nameuse{OP@a@\the\count@i}=0 - \advance\count@i by-1 - \advance\count@z by1 + \ifnum\@nameuse{OP@a@\the\op@count@i}=0 + \advance\op@count@i by-1 + \advance\op@count@z by1 \repeat - \count@i=\op@firstlength - \advance\count@i by\count@z - \xdef\op@firstlength{\the\count@i}% + \op@count@i=\op@firstlength + \advance\op@count@i by\op@count@z + \xdef\op@firstlength{\the\op@count@i}% \setbox2=\vbox{% - \count@i=\op@firstlength - \advance\count@i by1 + \op@count@i=\op@firstlength + \advance\op@count@i by1 \hbox{% \ifx\op@displayintermediary\op@string@none\else \kern\opcolumnwidth - \advance\count@i by1 + \advance\op@count@i by1 \fi \ifop@dividendbridge \vrule width0pt depth0pt height\oplineheight @@ -2188,19 +2261,19 @@ \fi \op@display{operandstyle.1}{a}% \ifnum\op@shift=0\relax\else - \count@v=\op@shift - \advance\count@v by\OP@a@d - \oplput(-\the\count@v,0){\op@strikedecimalsepsymbol}% + \op@count@v=\op@shift + \advance\op@count@v by\OP@a@d + \oplput(-\the\op@count@v,0){\op@strikedecimalsepsymbol}% \fi }% - \count@z=\OP@q@w - \count@ii=1\relax + \op@count@z=\OP@q@w + \op@count@ii=1\relax \ifx\op@displayintermediary\op@string@none - \advance\count@i by-1\relax + \advance\op@count@i by-1\relax \else - \count@iv=\@nameuse{OP@q@\the\count@z}\relax - \count@iii=\count@i - \advance\count@iii by-\@nameuse{OP@T\the\count@iv @w}% + \op@count@iv=\@nameuse{OP@q@\the\op@count@z}\relax + \op@count@iii=\op@count@i + \advance\op@count@iii by-\@nameuse{OP@T\the\op@count@iv @w}% \hbox{% \ifx\op@voperator\op@string@center \oplput(0,0.5){\op@subsymbol}% @@ -2210,31 +2283,31 @@ \oplput(0,0){\op@subsymbol}% \fi\fi \ophline(1,-0.25){\op@firstlength}% - \advance\count@ii by1 - \kern\count@iii\opcolumnwidth + \advance\op@count@ii by1 + \kern\op@count@iii\opcolumnwidth \op@display{intermediarystyle.1}% - {T\the\count@iv}% + {T\the\op@count@iv}% }% \fi {\global\setbox4=\hbox{}\setbox4=\box4}% \loop - \advance\count@z by-1 - \advance\count@i by1\relax - \ifnum\count@z>0\relax - \count@iv=\@nameuse{OP@q@\the\count@z}\relax - \ifnum\count@iv=0 + \advance\op@count@z by-1 + \advance\op@count@i by1\relax + \ifnum\op@count@z>0\relax + \op@count@iv=\@nameuse{OP@q@\the\op@count@z}\relax + \ifnum\op@count@iv=0 \ifx\op@displayintermediary\op@string@all - \count@v=\count@i - \advance\count@v by-\@nameuse{OP@R\the\count@ii @w}% + \op@count@v=\op@count@i + \advance\op@count@v by-\@nameuse{OP@R\the\op@count@ii @w}% \hbox{% - \kern\count@v\opcolumnwidth - \op@display{remainderstyle.\the\count@ii}% - {R\the\count@ii}% + \kern\op@count@v\opcolumnwidth + \op@display{remainderstyle.\the\op@count@ii}% + {R\the\op@count@ii}% }% - \count@iii=\count@i - \advance\count@iii by-\@nameuse{OP@T\the\count@iv @w}% + \op@count@iii=\op@count@i + \advance\op@count@iii by-\@nameuse{OP@T\the\op@count@iv @w}% \hbox{% - \kern\count@v\opcolumnwidth + \kern\op@count@v\opcolumnwidth \ifx\op@voperator\op@string@center \oplput(-1,0.5){\op@subsymbol}% \else\ifx\op@voperator\op@string@top @@ -2242,39 +2315,39 @@ \else \oplput(-1,0){\op@subsymbol}% \fi\fi - \ophline(0,-0.25){\@nameuse{OP@R\the\count@ii @w}}% - \kern-\count@v\opcolumnwidth - \kern\count@iii\opcolumnwidth - \op@display{intermediarystyle.\the\count@ii}% - {T\the\count@iv}% + \ophline(0,-0.25){\@nameuse{OP@R\the\op@count@ii @w}}% + \kern-\op@count@v\opcolumnwidth + \kern\op@count@iii\opcolumnwidth + \op@display{intermediarystyle.\the\op@count@ii}% + {T\the\op@count@iv}% }% \else - \ifnum\@nameuse{OP@R\the\count@ii @w}=2 - \ifnum\@nameuse{OP@R\the\count@ii @2}=0 - \op@makebox{1}{0}{remainderstyle.\the\count@ii.1}{zero}% + \ifnum\@nameuse{OP@R\the\op@count@ii @w}=2 + \ifnum\@nameuse{OP@R\the\op@count@ii @2}=0 + \op@makebox{1}{0}{remainderstyle.\the\op@count@ii.1}{zero}% \setbox4=\hbox to\opcolumnwidth{\hss\box0\hss}% \fi \fi \fi - \advance\count@ii by1\relax + \advance\op@count@ii by1\relax \else - \count@v=\count@i - \advance\count@v by-\@nameuse{OP@R\the\count@ii @w}% + \op@count@v=\op@count@i + \advance\op@count@v by-\@nameuse{OP@R\the\op@count@ii @w}% \ifvoid4\relax\else - \advance\count@v by-1 + \advance\op@count@v by-1 \fi \hbox{% - \kern\count@v\opcolumnwidth\copy4 - \op@display{remainderstyle.\the\count@ii}% - {R\the\count@ii}% + \kern\op@count@v\opcolumnwidth\copy4 + \op@display{remainderstyle.\the\op@count@ii}% + {R\the\op@count@ii}% }% - \advance\count@ii by1\relax + \advance\op@count@ii by1\relax \ifx\op@displayintermediary\op@string@none \else - \count@iii=\count@i - \advance\count@iii by-\@nameuse{OP@T\the\count@iv @w}% + \op@count@iii=\op@count@i + \advance\op@count@iii by-\@nameuse{OP@T\the\op@count@iv @w}% \hbox{% - \kern\count@v\opcolumnwidth + \kern\op@count@v\opcolumnwidth \ifx\op@voperator\op@string@center \oplput(-1,0.5){\op@subsymbol}% \else\ifx\op@voperator\op@string@top @@ -2282,40 +2355,40 @@ \else \oplput(-1,0){\op@subsymbol}% \fi\fi - \advance\count@ii by-1 + \advance\op@count@ii by-1 \ifvoid4\relax - \ophline(0,-0.25){\@nameuse{OP@R\the\count@ii @w}}% + \ophline(0,-0.25){\@nameuse{OP@R\the\op@count@ii @w}}% \else - \ophline(0,-0.25){\@nameuse{OP@T\the\count@iv @w}}% - \ophline(\@nameuse{OP@T\the\count@iv @w},-0.25){1}% + \ophline(0,-0.25){\@nameuse{OP@T\the\op@count@iv @w}}% + \ophline(\@nameuse{OP@T\the\op@count@iv @w},-0.25){1}% {\setbox4=\box4}% \fi - \advance\count@ii by1 - \kern-\count@v\opcolumnwidth - \kern\count@iii\opcolumnwidth - \op@display{intermediarystyle.\the\count@ii}% - {T\the\count@iv}% + \advance\op@count@ii by1 + \kern-\op@count@v\opcolumnwidth + \kern\op@count@iii\opcolumnwidth + \op@display{intermediarystyle.\the\op@count@ii}% + {T\the\op@count@iv}% }% \fi \fi \repeat - \advance\count@i by-1 - \count@iii=\count@i - \advance\count@iii by-\@nameuse{OP@R\the\count@ii @w}% + \advance\op@count@i by-1 + \op@count@iii=\op@count@i + \advance\op@count@iii by-\@nameuse{OP@R\the\op@count@ii @w}% \hbox{% - \kern\count@iii\opcolumnwidth - \op@display{remainderstyle.\the\count@ii}% - {R\the\count@ii}% + \kern\op@count@iii\opcolumnwidth + \op@display{remainderstyle.\the\op@count@ii}% + {R\the\op@count@ii}% }% }% \setbox3=\vbox{% - \count@v=\op@max{\OP@qq@w}{\OP@b@w} - \hbox{\ophline(-0.5,-0.25){\the\count@v.5}% + \op@count@v=\op@max{\OP@qq@w}{\OP@b@w} + \hbox{\ophline(-0.5,-0.25){\the\op@count@v.5}% \op@display{operandstyle.2}{b}% \ifnum\op@shift=0\relax\else - \count@v=\op@shift - \advance\count@v by\OP@b@d - \oplput(-\the\count@v,0){\op@strikedecimalsepsymbol}% + \op@count@v=\op@shift + \advance\op@count@v by\OP@b@d + \oplput(-\the\op@count@v,0){\op@strikedecimalsepsymbol}% \fi} \hbox{\op@display{resultstyle}{qq}} }% @@ -2357,10 +2430,14 @@ \def\op@divmode{#1}% \op@copy{#2}{da}% \op@copy{#3}{db}% - \count@iv=0 - \count@iii=\op@max{\OP@da@d}{\OP@db@d}\relax - \op@powten{da}{\the\count@iii}% - \op@powten{db}{\the\count@iii}% + \op@count@iv=0 + \op@count@iii=\op@max{\OP@da@d}{\OP@db@d}\relax + \op@powten{da}{\the\op@count@iii}% + \op@powten{db}{\the\op@count@iii}% +% add 0.23 + \op@unzero{da}% + \op@unzero{db}% +% end 0.23 \ifnum\op@divmode=1 \op@cmp{da}{maxinteger}% \ifopgt @@ -2387,29 +2464,29 @@ \fi\fi \fi \op@multable{db}% + \op@copy{da}{R}% \op@cmp{da}{db}% \ifople - \op@copy{da}{R}% - \count@i=\OP@da@w + \op@count@i=\OP@da@w \else \xdef\OP@R@d{0}% \xdef\OP@R@s{0}% - \count@i=\@nameuse{OP@db@w}% - \op@leftdividend{\the\count@i}% + \op@count@i=\@nameuse{OP@db@w}% + \op@leftdividend{\the\op@count@i}% \op@cmp{R}{db}% \ifoplt - \ifnum\OP@da@w>\count@i - \advance\count@i by1 - \op@leftdividend{\the\count@i}% + \ifnum\OP@da@w>\op@count@i + \advance\op@count@i by1 + \op@leftdividend{\the\op@count@i}% \fi \fi \fi - \xdef\op@firstlength{\the\count@i}% - \count@i=-\count@i - \advance\count@i by\OP@da@w + \xdef\op@firstlength{\the\op@count@i}% + \op@count@i=-\op@count@i + \advance\op@count@i by\OP@da@w \op@copy{R}{R0}% \op@copy{zero}{dq}% - \count@ii=0 + \op@count@ii=0 \op@againtrue \loop \ifop@again @@ -2419,96 +2496,96 @@ \op@sub{R}{T\op@k}{dr}% \op@unzero{T\op@k}% \op@multen{dr}% - \ifnum\count@i>0 - \@namexdef{OP@dr@1}{\@nameuse{OP@da@\the\count@i}}% + \ifnum\op@count@i>0 + \@namexdef{OP@dr@1}{\@nameuse{OP@da@\the\op@count@i}}% \fi - \advance\count@i by-1\relax + \advance\op@count@i by-1\relax \op@unzero{dr}% \ifnum\OP@dr@w=1 \xdef\OP@dr@w{2}% \xdef\OP@dr@i{2}% \@namexdef{OP@dr@2}{0}% \fi - \advance\count@ii by1\relax - \op@copy{dr}{R\the\count@ii}% + \advance\op@count@ii by1\relax + \op@copy{dr}{R\the\op@count@ii}% \op@copy{dr}{R}% \ifcase\op@divmode\relax - \ifnum\count@ii<\op@maxdivstep\relax\else + \ifnum\op@count@ii<\op@maxdivstep\relax\else \op@againfalse \fi - \ifnum\count@i<0\relax% + \ifnum\op@count@i<0\relax% \op@cmp{zero}{R}% \ifopeq \op@againfalse \fi \fi \or - \ifnum\count@ii<\op@safedivstep\relax\else + \ifnum\op@count@ii<\op@safedivstep\relax\else \op@againfalse \fi - \ifnum\count@i<-\op@lengthperiod\relax - \count@iv=\count@ii - \advance\count@iv by-\op@lengthperiod - \op@cmp{R\the\count@iv}{R\the\count@ii}% + \ifnum\op@count@i<-\op@lengthperiod\relax + \op@count@iv=\op@count@ii + \advance\op@count@iv by-\op@lengthperiod + \op@cmp{R\the\op@count@iv}{R\the\op@count@ii}% \ifopeq \op@againfalse \fi \fi \or - \ifnum\count@i=-1 + \ifnum\op@count@i=-1 \op@againfalse \fi \fi \repeat \op@copy{zero}{T0}% - \advance\count@i by1\relax - \ifnum\count@i<0 - \xdef\OP@dq@d{-\the\count@i}% - \count@z=\OP@dq@w - \advance\count@z by\count@i - \xdef\OP@dq@i{\the\count@z}% + \advance\op@count@i by1\relax + \ifnum\op@count@i<0 + \xdef\OP@dq@d{-\the\op@count@i}% + \op@count@z=\OP@dq@w + \advance\op@count@z by\op@count@i + \xdef\OP@dq@i{\the\op@count@z}% \fi \op@unzero{dq}% \op@copy{dq}{#4}% \op@unzero{dr}% \op@copy{dr}{R}% \op@rshift{1}{dr}% - \op@copy{dr}{R\the\count@ii}% - \count@i=\count@iii - \advance\count@i by1 - \advance\count@i by\OP@dq@d\relax - \count@ii=\count@i - \advance\count@ii by\OP@R@w - \op@format{\the\count@ii}{0}{R}% - \count@z=\OP@R@w - \advance\count@z by-\count@i - \xdef\OP@R@i{\the\count@z}% - \xdef\OP@R@d{\the\count@i}% + \op@copy{dr}{R\the\op@count@ii}% + \op@count@i=\op@count@iii + \advance\op@count@i by1 + \advance\op@count@i by\OP@dq@d\relax + \op@count@ii=\op@count@i + \advance\op@count@ii by\OP@R@w + \op@format{\the\op@count@ii}{0}{R}% + \op@count@z=\OP@R@w + \advance\op@count@z by-\op@count@i + \xdef\OP@R@i{\the\op@count@z}% + \xdef\OP@R@d{\the\op@count@i}% \op@unzero{R}% \op@copy{R}{#5}% \endgroup } \def\op@powten#1#2{% \begingroup - \count@z=#2\relax - \advance\count@z by-\@nameuse{OP@#1@d}% + \op@count@z=#2\relax + \advance\op@count@z by-\@nameuse{OP@#1@d}% \@namexdef{OP@#1@d}{0}% - \count@i=\@nameuse{OP@#1@w}% - \advance\count@i by\count@z - \@namexdef{OP@#1@w}{\the\count@i}% - \@namexdef{OP@#1@i}{\the\count@i}% - \count@ii=\count@i - \advance\count@ii by-\count@z + \op@count@i=\@nameuse{OP@#1@w}% + \advance\op@count@i by\op@count@z + \@namexdef{OP@#1@w}{\the\op@count@i}% + \@namexdef{OP@#1@i}{\the\op@count@i}% + \op@count@ii=\op@count@i + \advance\op@count@ii by-\op@count@z \loop - \ifnum\count@ii>0 - \@namexdef{OP@#1@\the\count@i}{\@nameuse{OP@#1@\the\count@ii}}% - \advance\count@i by-1 - \advance\count@ii by-1 + \ifnum\op@count@ii>0 + \@namexdef{OP@#1@\the\op@count@i}{\@nameuse{OP@#1@\the\op@count@ii}}% + \advance\op@count@i by-1 + \advance\op@count@ii by-1 \repeat \loop - \ifnum\count@i>0 - \@namexdef{OP@#1@\the\count@i}{0}% - \advance\count@i by-1 + \ifnum\op@count@i>0 + \@namexdef{OP@#1@\the\op@count@i}{0}% + \advance\op@count@i by-1 \repeat \endgroup } @@ -2558,15 +2635,15 @@ } \def\op@divperiod#1#2#3{% \begingroup - \count@i=#1\relax - \count@ii=#2\relax - \ifnum\count@ii=0\relax + \op@count@i=#1\relax + \op@count@ii=#2\relax + \ifnum\op@count@ii=0\relax \@namexdef{#3}{1}% \else - \op@gcd{\the\count@i}{\the\count@ii}{op@tmp}% - \count@iii=\op@tmp - \divide\count@ii by\count@iii - \op@twofiveQ{\the\count@ii}{op@tmp}% + \op@gcd{\the\op@count@i}{\the\op@count@ii}{op@tmp}% + \op@count@iii=\op@tmp + \divide\op@count@ii by\op@count@iii + \op@twofiveQ{\the\op@count@ii}{op@tmp}% \op@order{\op@tmp}{op@tmp}% \@namexdef{#3}{\op@tmp}% \fi @@ -2616,83 +2693,83 @@ } \def\op@gcd#1#2#3{% \begingroup - \count@i=#1\relax - \count@ii=#2\relax + \op@count@i=#1\relax + \op@count@ii=#2\relax \loop - \count@iii=\count@i - \divide\count@iii by\count@ii - \multiply\count@iii by\count@ii - \advance\count@i by-\count@iii - \count@iii=\count@i\relax - \count@i=\count@ii\relax - \count@ii=\count@iii - \ifnum\count@ii>0 + \op@count@iii=\op@count@i + \divide\op@count@iii by\op@count@ii + \multiply\op@count@iii by\op@count@ii + \advance\op@count@i by-\op@count@iii + \op@count@iii=\op@count@i\relax + \op@count@i=\op@count@ii\relax + \op@count@ii=\op@count@iii + \ifnum\op@count@ii>0 \repeat - \@namexdef{#3}{\the\count@i}% + \@namexdef{#3}{\the\op@count@i}% \endgroup } \def\op@twofiveQ#1#2{% \begingroup - \count@i=#1\relax + \op@count@i=#1\relax \loop - \count@ii=\count@i - \divide\count@ii by2 - \multiply\count@ii by2 - \ifnum\count@ii=\count@i - \divide\count@i by2 + \op@count@ii=\op@count@i + \divide\op@count@ii by2 + \multiply\op@count@ii by2 + \ifnum\op@count@ii=\op@count@i + \divide\op@count@i by2 \repeat \loop - \count@ii=\count@i - \divide\count@ii by5 - \multiply\count@ii by5 - \ifnum\count@ii=\count@i - \divide\count@i by5 + \op@count@ii=\op@count@i + \divide\op@count@ii by5 + \multiply\op@count@ii by5 + \ifnum\op@count@ii=\op@count@i + \divide\op@count@i by5 \repeat - \@namexdef{#2}{\the\count@i}% + \@namexdef{#2}{\the\op@count@i}% \endgroup } \def\op@order#1#2{% \begingroup - \count@i=1\relax - \count@ii=0 + \op@count@i=1\relax + \op@count@ii=0 \loop - \multiply\count@i by10 - \count@iii=\count@i - \divide\count@iii by#1\relax - \multiply\count@iii by#1\relax - \advance\count@i by-\count@iii - \advance\count@ii by1 - \ifnum\count@i>1 + \multiply\op@count@i by10 + \op@count@iii=\op@count@i + \divide\op@count@iii by#1\relax + \multiply\op@count@iii by#1\relax + \advance\op@count@i by-\op@count@iii + \advance\op@count@ii by1 + \ifnum\op@count@i>1 \repeat - \@namexdef{#2}{\the\count@ii} + \@namexdef{#2}{\the\op@count@ii} \endgroup } \def\op@leftdividend#1{% \begingroup - \count@z=#1\relax - \count@i=\OP@da@w - \xdef\OP@R@w{\the\count@z}% - \xdef\OP@R@i{\the\count@z}% + \op@count@z=#1\relax + \op@count@i=\OP@da@w + \xdef\OP@R@w{\the\op@count@z}% + \xdef\OP@R@i{\the\op@count@z}% \loop - \@namexdef{OP@R@\the\count@z}{\@nameuse{OP@da@\the\count@i}}% - \advance\count@i by-1 - \advance\count@z by-1 - \ifnum\count@z>0 + \@namexdef{OP@R@\the\op@count@z}{\@nameuse{OP@da@\the\op@count@i}}% + \advance\op@count@i by-1 + \advance\op@count@z by-1 + \ifnum\op@count@z>0 \repeat \endgroup } \def\op@multen#1{% \begingroup - \count@z=\@nameuse{OP@#1@w}\relax - \count@i=\count@z - \advance\count@i by1 - \@namexdef{OP@#1@w}{\the\count@i}% - \@namexdef{OP@#1@i}{\the\count@i}% + \op@count@z=\@nameuse{OP@#1@w}\relax + \op@count@i=\op@count@z + \advance\op@count@i by1 + \@namexdef{OP@#1@w}{\the\op@count@i}% + \@namexdef{OP@#1@i}{\the\op@count@i}% \loop - \ifnum\count@z>0 - \@namexdef{OP@#1@\the\count@i}{\@nameuse{OP@#1@\the\count@z}}% - \advance\count@z by-1 - \advance\count@i by-1 + \ifnum\op@count@z>0 + \@namexdef{OP@#1@\the\op@count@i}{\@nameuse{OP@#1@\the\op@count@z}}% + \advance\op@count@z by-1 + \advance\op@count@i by-1 \repeat \@namexdef{OP@#1@1}{0}% \endgroup @@ -2700,32 +2777,32 @@ \def\op@mulpowerten#1#2{% \begingroup \ifnum\@nameuse{OP@#1@d}<#2\relax - \count@z=#2\relax - \advance\count@z by-\@nameuse{OP@#1@d}\relax - \count@ii=\@nameuse{OP@#1@w}% - \count@i=\@nameuse{OP@#1@w}% - \advance\count@i by\count@z - \@namexdef{OP@#1@w}{\the\count@i}% - \@namexdef{OP@#1@i}{\the\count@i}% + \op@count@z=#2\relax + \advance\op@count@z by-\@nameuse{OP@#1@d}\relax + \op@count@ii=\@nameuse{OP@#1@w}% + \op@count@i=\@nameuse{OP@#1@w}% + \advance\op@count@i by\op@count@z + \@namexdef{OP@#1@w}{\the\op@count@i}% + \@namexdef{OP@#1@i}{\the\op@count@i}% \@namexdef{OP@#1@d}{0}% \loop - \ifnum\count@ii>0 - \@namexdef{OP@#1@\the\count@i}{\@nameuse{OP@#1@\the\count@ii}}% - \advance\count@i by-1 - \advance\count@ii by-1 + \ifnum\op@count@ii>0 + \@namexdef{OP@#1@\the\op@count@i}{\@nameuse{OP@#1@\the\op@count@ii}}% + \advance\op@count@i by-1 + \advance\op@count@ii by-1 \repeat \loop - \ifnum\count@z>0 - \@namexdef{OP@#1@\the\count@z}{0}% - \advance\count@z by-1\relax + \ifnum\op@count@z>0 + \@namexdef{OP@#1@\the\op@count@z}{0}% + \advance\op@count@z by-1\relax \repeat \else - \count@z=\@nameuse{OP@#1@d}\relax - \advance\count@z by-#2\relax - \@namexdef{OP@#1@d}{\the\count@z}% - \count@z=\@nameuse{OP@#1@i}\relax - \advance\count@z by#2\relax - \@namexdef{OP@#1@i}{\the\count@z}% + \op@count@z=\@nameuse{OP@#1@d}\relax + \advance\op@count@z by-#2\relax + \@namexdef{OP@#1@d}{\the\op@count@z}% + \op@count@z=\@nameuse{OP@#1@i}\relax + \advance\op@count@z by#2\relax + \@namexdef{OP@#1@i}{\the\op@count@z}% \fi \op@unzero{#1}% \endgroup @@ -2733,25 +2810,25 @@ \def\op@divpowerten#1#2{% \begingroup \ifnum\@nameuse{OP@#1@i}>#2\relax - \count@z=\@nameuse{OP@#1@d}\relax - \advance\count@z by#2\relax - \@namexdef{OP@#1@d}{\the\count@z}% - \count@z=\@nameuse{OP@#1@i}\relax - \advance\count@z by-#2\relax - \@namexdef{OP@#1@i}{\the\count@z}% + \op@count@z=\@nameuse{OP@#1@d}\relax + \advance\op@count@z by#2\relax + \@namexdef{OP@#1@d}{\the\op@count@z}% + \op@count@z=\@nameuse{OP@#1@i}\relax + \advance\op@count@z by-#2\relax + \@namexdef{OP@#1@i}{\the\op@count@z}% \else - \count@z=\@nameuse{OP@#1@d}\relax - \advance\count@z by#2\relax - \@namexdef{OP@#1@d}{\the\count@z}% + \op@count@z=\@nameuse{OP@#1@d}\relax + \advance\op@count@z by#2\relax + \@namexdef{OP@#1@d}{\the\op@count@z}% \@namexdef{OP@#1@i}{1}% - \advance\count@z by1\relax - \count@i=\@nameuse{OP@#1@w}% - \@namexdef{OP@#1@w}{\the\count@z}% - \advance\count@z by1 + \advance\op@count@z by1\relax + \op@count@i=\@nameuse{OP@#1@w}% + \@namexdef{OP@#1@w}{\the\op@count@z}% + \advance\op@count@z by1 \loop - \ifnum\count@i<\count@z - \advance\count@i by1 - \@namexdef{OP@#1@\the\count@i}{0}% + \ifnum\op@count@i<\op@count@z + \advance\op@count@i by1 + \@namexdef{OP@#1@\the\op@count@i}{0}% \repeat \fi \op@unzero{#1}% @@ -2823,17 +2900,17 @@ \def\op@integer#1#2{% \begingroup \op@unzero{#1}% - \count@z=\@nameuse{OP@#1@d}\relax - \ifnum\count@z>0\relax - \count@i=0 + \op@count@z=\@nameuse{OP@#1@d}\relax + \ifnum\op@count@z>0\relax + \op@count@i=0 \loop - \ifnum\count@z<\@nameuse{OP@#1@w}% - \advance\count@z by1\relax - \advance\count@i by1\relax - \@namexdef{OP@#2@\the\count@i}{\@nameuse{OP@#1@\the\count@z}}% + \ifnum\op@count@z<\@nameuse{OP@#1@w}% + \advance\op@count@z by1\relax + \advance\op@count@i by1\relax + \@namexdef{OP@#2@\the\op@count@i}{\@nameuse{OP@#1@\the\op@count@z}}% \repeat - \@namexdef{OP@#2@w}{\the\count@i}% - \@namexdef{OP@#2@i}{\the\count@i}% + \@namexdef{OP@#2@w}{\the\op@count@i}% + \@namexdef{OP@#2@i}{\the\op@count@i}% \@namexdef{OP@#2@d}{0}% \else \op@copy{#1}{#2}% @@ -2888,17 +2965,17 @@ \op@unsplit{b}{@b}% \@namexdef{OP@a@#2}{\Op@@b}% \ifnum\OP@a@w<#2\relax - \count@z=\OP@a@w\relax - \advance\count@z by1\relax + \op@count@z=\OP@a@w\relax + \advance\op@count@z by1\relax \loop - \ifnum\count@z<#2\relax - \@namexdef{OP@a@\the\count@z}{0}% - \advance\count@z by1 + \ifnum\op@count@z<#2\relax + \@namexdef{OP@a@\the\op@count@z}{0}% + \advance\op@count@z by1 \repeat \xdef\OP@a@w{#2}% - \count@z=#2\relax - \advance\count@z by-\OP@a@d - \xdef\OP@a@i{\the\count@z}% + \op@count@z=#2\relax + \advance\op@count@z by-\OP@a@d + \xdef\OP@a@i{\the\op@count@z}% \fi \op@unsplit{a}{#1}% \fi @@ -2910,10 +2987,10 @@ \ifop@error \op@errorwrite \else - \count@z=\OP@a@d - \advance\count@z by#2\relax - \ifnum\OP@a@w>\count@z\relax - \@namexdef{Op@#3}{\@nameuse{OP@a@\the\count@z}}% + \op@count@z=\OP@a@d + \advance\op@count@z by#2\relax + \ifnum\OP@a@w>\op@count@z\relax + \@namexdef{Op@#3}{\@nameuse{OP@a@\the\op@count@z}}% \else \@namexdef{Op@#3}{0}% \fi @@ -2928,20 +3005,20 @@ \op@errorwrite \else \op@unsplit{b}{@b}% - \count@z=\OP@a@d - \advance\count@z by#2\relax - \@namexdef{OP@a@\the\count@z}{\Op@@b}% - \ifnum\OP@a@w>\count@z\relax\else - \count@i=\OP@a@w - \xdef\OP@a@w{\the\count@z}% - \advance\count@i by1 + \op@count@z=\OP@a@d + \advance\op@count@z by#2\relax + \@namexdef{OP@a@\the\op@count@z}{\Op@@b}% + \ifnum\OP@a@w>\op@count@z\relax\else + \op@count@i=\OP@a@w + \xdef\OP@a@w{\the\op@count@z}% + \advance\op@count@i by1 \loop - \ifnum\count@i<\count@z - \@namexdef{OP@a@\the\count@i}{0}% - \advance\count@i by1 + \ifnum\op@count@i<\op@count@z + \@namexdef{OP@a@\the\op@count@i}{0}% + \advance\op@count@i by1 \repeat - \advance\count@z by-\OP@a@d - \xdef\OP@a@i{\the\count@z}% + \advance\op@count@z by-\OP@a@d + \xdef\OP@a@i{\the\op@count@z}% \fi \op@unsplit{a}{#1}% \fi @@ -2956,10 +3033,10 @@ \ifnum\OP@a@d<#2\relax \@namexdef{Op@#3}{0}% \else - \count@z=\OP@a@d - \advance\count@z by-#2\relax - \advance\count@z by1 - \@namexdef{Op@#3}{\@nameuse{OP@a@\the\count@z}}% + \op@count@z=\OP@a@d + \advance\op@count@z by-#2\relax + \advance\op@count@z by1 + \@namexdef{Op@#3}{\@nameuse{OP@a@\the\op@count@z}}% \fi \fi \endgroup @@ -2973,31 +3050,42 @@ \else \op@unsplit{b}{@b}% \ifnum\OP@a@d<\Op@@b\relax - \count@z=\Op@@b - \advance\count@z by-\OP@a@d - \advance\count@z by1\relax - \count@i=\OP@a@w - \advance\count@i by\count@z\relax - \count@z=\OP@a@w - \xdef\OP@a@w{\the\count@i}% + \op@count@z=\Op@@b + \advance\op@count@z by-\OP@a@d +%%% [2006/10/06] Bug find by Dave Jarvis. +% \advance\op@count@z by1\relax +%%% end bug fixing + \op@count@i=\OP@a@w + \advance\op@count@i by\op@count@z\relax + \op@count@z=\OP@a@w + \xdef\OP@a@w{\the\op@count@i}% \xdef\OP@a@d{\Op@@b}% \loop - \ifnum\count@z>0 - \@namexdef{OP@a@\the\count@i}{\@nameuse{OP@a@\the\count@z}}% - \advance\count@z by-1 - \advance\count@i by-1 + \ifnum\op@count@z>0 + \@namexdef{OP@a@\the\op@count@i}{\@nameuse{OP@a@\the\op@count@z}}% + \advance\op@count@z by-1 + \advance\op@count@i by-1 \repeat \loop - \ifnum\count@i>1 - \@namexdef{OP@a@\the\count@i}{0}% - \advance\count@i by-1 + \ifnum\op@count@i>1 + \@namexdef{OP@a@\the\op@count@i}{0}% + \advance\op@count@i by-1 \repeat - \@namexdef{OP@a@1}{\Op@@b}% +%%% [2006/10/06] Bug find by Dave Jarvis. +% \@namexdef{OP@a@1}{\Op@@b}% + \@namexdef{OP@a@1}{#2}% +%%% end bug fixing \else - \count@z=\OP@a@d - \advance\count@z by-#2\relax - \advance\count@z by1 - \@namexdef{OP@a@\the\count@z}{\Op@@b}% + \op@count@z=\OP@a@d +%%% [2006/10/06] Bug find by Dave Jarvis. +% \advance\op@count@z by-#2\relax + \advance\op@count@z by-\Op@@b\relax +%%% end bug fixing + \advance\op@count@z by1 +%%% [2006/10/06] Bug find by Dave Jarvis. +% \@namexdef{OP@a@\the\op@count@z}{\Op@@b}% + \@namexdef{OP@a@\the\op@count@z}{#2}% +%%% end bug fixing \fi \op@unsplit{a}{#1}% \fi @@ -3009,17 +3097,17 @@ \ifop@error \op@errorwrite \else - \count@z=\OP@a@w\relax - \count@i=0\relax + \op@count@z=\OP@a@w\relax + \op@count@i=0\relax \loop - \ifnum\count@z>0 - \advance\count@i by\@nameuse{OP@a@\the\count@z}\relax - \ifnum\count@i>8 - \advance\count@i by-9 + \ifnum\op@count@z>0 + \advance\op@count@i by\@nameuse{OP@a@\the\op@count@z}\relax + \ifnum\op@count@i>8 + \advance\op@count@i by-9 \fi - \advance\count@z by-1 + \advance\op@count@z by-1 \repeat - \opcopy{\the\count@i}{#2}% + \opcopy{\the\op@count@i}{#2}% \fi \endgroup } @@ -3029,28 +3117,28 @@ \ifop@error \op@errorwrite \else - \count@ii=\OP@a@w - \advance\count@ii by1\relax - \count@i=0\relax - \count@z=-1\relax + \op@count@ii=\OP@a@w + \advance\op@count@ii by1\relax + \op@count@i=0\relax + \op@count@z=-1\relax \loop - \advance\count@z by2\relax - \ifnum\count@z<\count@ii - \advance\count@i by\@nameuse{OP@a@\the\count@z}\relax - \ifnum\count@i>10 - \advance\count@i by-11 + \advance\op@count@z by2\relax + \ifnum\op@count@z<\op@count@ii + \advance\op@count@i by\@nameuse{OP@a@\the\op@count@z}\relax + \ifnum\op@count@i>10 + \advance\op@count@i by-11 \fi \repeat - \count@z=0\relax + \op@count@z=0\relax \loop - \advance\count@z by2\relax - \ifnum\count@z<\count@ii - \advance\count@i by-\@nameuse{OP@a@\the\count@z}\relax - \ifnum\count@i<0 - \advance\count@i by11 + \advance\op@count@z by2\relax + \ifnum\op@count@z<\op@count@ii + \advance\op@count@i by-\@nameuse{OP@a@\the\op@count@z}\relax + \ifnum\op@count@i<0 + \advance\op@count@i by11 \fi \repeat - \opcopy{\the\count@i}{#2}% + \opcopy{\the\op@count@i}{#2}% \fi \endgroup } @@ -3075,9 +3163,9 @@ \op@againtrue \fi\fi\fi \ifop@again - \count@z=1 - \advance\count@z by-\@nameuse{OP@#2@s}\relax - \@namexdef{OP@#2@s}{\the\count@z}% + \op@count@z=1 + \advance\op@count@z by-\@nameuse{OP@#2@s}\relax + \@namexdef{OP@#2@s}{\the\op@count@z}% \fi \endgroup } @@ -3126,30 +3214,30 @@ \op@error{Exponent is too big (>1073741824)}% {Sorry}% \else - \count@z=0 + \op@count@z=0 \@namexdef{Op@@e0}{1}% \xdef\Op@@tmp{1}% \@namexdef{Op@@p0}{\Op@@a}% \@namexdef{Op@@ptmp}{\@nameuse{Op@@p0}}% \loop - \ifnum\@nameuse{Op@@e\the\count@z}<\Op@@b + \ifnum\@nameuse{Op@@e\the\op@count@z}<\Op@@b \opadd*{@tmp}{@tmp}{@@tmp}% \opmul*{@ptmp}{@ptmp}{@@ptmp}% - \advance\count@z by1 + \advance\op@count@z by1 \xdef\Op@@tmp{\Op@@@tmp}% \xdef\Op@@ptmp{\Op@@@ptmp}% - \@namexdef{Op@@e\the\count@z}{\Op@@@tmp}% - \@namexdef{Op@@p\the\count@z}{\Op@@@ptmp}% + \@namexdef{Op@@e\the\op@count@z}{\Op@@@tmp}% + \@namexdef{Op@@p\the\op@count@z}{\Op@@@ptmp}% \repeat \opcopy{1}{@r}% \loop \ifnum\Op@@b>0\relax - \ifnum\Op@@b<\@nameuse{Op@@e\the\count@z}\relax + \ifnum\Op@@b<\@nameuse{Op@@e\the\op@count@z}\relax \else - \opmul*{@r}{@p\the\count@z}{@r}% - \opsub*{@b}{@e\the\count@z}{@b}% + \opmul*{@r}{@p\the\op@count@z}{@r}% + \opsub*{@b}{@e\the\op@count@z}{@b}% \fi - \advance\count@z by-1 + \advance\op@count@z by-1 \repeat \opcopy{@r}{#3}% \fi @@ -3187,9 +3275,9 @@ \opneg{@rb}{@rb}% \ifnum\Op@@rb<\@nameuse{OP@ra@i}\relax \else - \count@z=\@nameuse{OP@ra@i}% - \advance\count@z by-1 - \xdef\Op@@rb{\the\count@z}% + \op@count@z=\@nameuse{OP@ra@i}% + \advance\op@count@z by-1 + \xdef\Op@@rb{\the\op@count@z}% \fi \opneg{@rb}{@rb}% \fi @@ -3226,56 +3314,56 @@ \begingroup \op@unsplit{#2}{@fb}% \op@unzero{#1}% - \count@z=\Op@@fb\relax - \ifnum\count@z<0 - \count@z=-\count@z - \ifnum\count@z<\@nameuse{OP@#1@i}\relax\else - \count@z=\@nameuse{OP@#1@i}% - \advance\count@z by-1 + \op@count@z=\Op@@fb\relax + \ifnum\op@count@z<0 + \op@count@z=-\op@count@z + \ifnum\op@count@z<\@nameuse{OP@#1@i}\relax\else + \op@count@z=\@nameuse{OP@#1@i}% + \advance\op@count@z by-1 \fi \op@integer{#1}{#1}% \loop - \ifnum\count@z>0 - \@namexdef{OP@#1@\the\count@z}{0}% - \advance\count@z by-1\relax + \ifnum\op@count@z>0 + \@namexdef{OP@#1@\the\op@count@z}{0}% + \advance\op@count@z by-1\relax \repeat \else - \ifnum\count@z>\@nameuse{OP@#1@d}% - \advance\count@z by-\@nameuse{OP@#1@d}% - \count@i=\@nameuse{OP@#1@d}% - \advance\count@i by\count@z - \@namexdef{OP@#1@d}{\the\count@i}% - \count@i=\@nameuse{OP@#1@w}\relax - \count@ii=\count@i - \advance\count@ii by\count@z - \@namexdef{OP@#1@w}{\the\count@ii}% + \ifnum\op@count@z>\@nameuse{OP@#1@d}% + \advance\op@count@z by-\@nameuse{OP@#1@d}% + \op@count@i=\@nameuse{OP@#1@d}% + \advance\op@count@i by\op@count@z + \@namexdef{OP@#1@d}{\the\op@count@i}% + \op@count@i=\@nameuse{OP@#1@w}\relax + \op@count@ii=\op@count@i + \advance\op@count@ii by\op@count@z + \@namexdef{OP@#1@w}{\the\op@count@ii}% \loop - \ifnum\count@i>0 - \@namexdef{OP@#1@\the\count@ii}{\@nameuse{OP@#1@\the\count@i}}% - \advance\count@i by-1 - \advance\count@ii by-1 + \ifnum\op@count@i>0 + \@namexdef{OP@#1@\the\op@count@ii}{\@nameuse{OP@#1@\the\op@count@i}}% + \advance\op@count@i by-1 + \advance\op@count@ii by-1 \repeat \loop - \ifnum\count@ii>0 - \@namexdef{OP@#1@\the\count@ii}{0}% - \advance\count@ii by-1 + \ifnum\op@count@ii>0 + \@namexdef{OP@#1@\the\op@count@ii}{0}% + \advance\op@count@ii by-1 \repeat \else - \advance\count@z by-\@nameuse{OP@#1@d}\relax - \count@z=-\count@z\relax - \count@i=\@nameuse{OP@#1@w}\relax - \count@ii=\count@i\relax - \advance\count@i by-\count@z - \@namexdef{OP@#1@w}{\the\count@i}\relax - \count@i=\@nameuse{OP@#1@d}\relax - \advance\count@i by-\count@z - \@namexdef{OP@#1@d}{\the\count@i}% - \count@i=0\relax + \advance\op@count@z by-\@nameuse{OP@#1@d}\relax + \op@count@z=-\op@count@z\relax + \op@count@i=\@nameuse{OP@#1@w}\relax + \op@count@ii=\op@count@i\relax + \advance\op@count@i by-\op@count@z + \@namexdef{OP@#1@w}{\the\op@count@i}\relax + \op@count@i=\@nameuse{OP@#1@d}\relax + \advance\op@count@i by-\op@count@z + \@namexdef{OP@#1@d}{\the\op@count@i}% + \op@count@i=0\relax \loop - \ifnum\count@z<\count@ii - \advance\count@z by1\relax - \advance\count@i by1 - \@namexdef{OP@#1@\the\count@i}{\@nameuse{OP@#1@\the\count@z}}% + \ifnum\op@count@z<\op@count@ii + \advance\op@count@z by1\relax + \advance\op@count@i by1 + \@namexdef{OP@#1@\the\op@count@i}{\@nameuse{OP@#1@\the\op@count@z}}% \repeat \fi \fi @@ -3285,10 +3373,10 @@ \op@unsplit{#1}{@Ca}% \op@unsplit{#2}{@Cb}% \op@unzero{#1}% - \count@z=\Op@@Cb\relax - \ifnum\count@z>0\relax - \ifnum\count@z<\@nameuse{OP@#1@d}\relax - \oppower{0.1}{\the\count@z}{@Cr}% + \op@count@z=\Op@@Cb\relax + \ifnum\op@count@z>0\relax + \ifnum\op@count@z<\@nameuse{OP@#1@d}\relax + \oppower{0.1}{\the\op@count@z}{@Cr}% \opadd*{@Ca}{@Cr}{@Ca}% \op@split{@Ca}{#1}% \op@split{@Cb}{#2}% @@ -3300,13 +3388,13 @@ \fi \else \opneg{@Cb}{@Cb}% - \count@z=-\count@z\relax - \ifnum\count@z<\@nameuse{OP@#1@i}\relax - \oppower{10}{\the\count@z}{@Cr}% + \op@count@z=-\op@count@z\relax + \ifnum\op@count@z<\@nameuse{OP@#1@i}\relax + \oppower{10}{\the\op@count@z}{@Cr}% \else - \count@z=\@nameuse{OP@#1@i}% - \advance\count@z by-1 - \oppower{10}{\the\count@z}{@Cr}% + \op@count@z=\@nameuse{OP@#1@i}% + \advance\op@count@z by-1 + \oppower{10}{\the\op@count@z}{@Cr}% \fi \opadd*{@Ca}{@Cr}{@Ca}% \opneg{@Cb}{@Cb}% @@ -3387,8 +3475,8 @@ \catcode`\ =12 \op@scan@@line } -\def\op@scan@@line#1{\op@scan@@@line#1\@nil\endgroup} -\def\op@scan@@@line#1#2\@nil{% +\def\op@scan@@line#1{\op@scan@@@line#1\op@nil\endgroup} +\def\op@scan@@@line#1#2\op@nil{% \op@testch@r{#1}% \ifop@isdigit \global\op@in@signfalse @@ -3482,293 +3570,293 @@ \else \let\next\op@scan@@@line \fi - \expandafter\next\@tempa\@nil + \expandafter\next\@tempa\op@nil } \def\op@search@subexpr#1#2{% \begingroup - \count@i=#1\relax - \count@v=#2\relax - \ifnum\count@i=\count@v + \op@count@i=#1\relax + \op@count@v=#2\relax + \ifnum\op@count@i=\op@count@v \op@token@use{#1}% \else - \count@iii=\count@v - \count@iv=\count@i - \advance\count@iv by-1 - \count@ii=0 + \op@count@iii=\op@count@v + \op@count@iv=\op@count@i + \advance\op@count@iv by-1 + \op@count@ii=0 \loop - \ifnum\count@iii>\count@iv - \expandafter\ifx\csname OP@token\the\count@iii\endcsname + \ifnum\op@count@iii>\op@count@iv + \expandafter\ifx\csname OP@token\the\op@count@iii\endcsname \op@string@rpar\relax \advance\op@parenthesis by1 \fi - \expandafter\ifx\csname OP@token\the\count@iii\endcsname + \expandafter\ifx\csname OP@token\the\op@count@iii\endcsname \op@string@lpar\relax \advance\op@parenthesis by-1 \fi - \expandafter\ifx\csname OP@token\the\count@iii\endcsname + \expandafter\ifx\csname OP@token\the\op@count@iii\endcsname \op@string@comma\relax \ifnum\op@parenthesis=0 - \count@ii=\count@iii\relax - \count@iii=0 + \op@count@ii=\op@count@iii\relax + \op@count@iii=0 \fi \fi - \advance\count@iii by-1 + \advance\op@count@iii by-1 \repeat - \ifnum\count@ii=0\relax + \ifnum\op@count@ii=0\relax \ifnum\op@parenthesis=0 - \op@search@term{\the\count@i}{\the\count@v}% + \op@search@term{\the\op@count@i}{\the\op@count@v}% \else \op@error{Unbalanced parenthesis in expression}% {Error between tokens #1 and #2}% \fi \else - \advance\count@ii by-1 - \op@search@subexpr{\the\count@i}{\the\count@ii}% - \advance\count@ii by2 - \op@search@subexpr{\the\count@ii}{\the\count@v}% + \advance\op@count@ii by-1 + \op@search@subexpr{\the\op@count@i}{\the\op@count@ii}% + \advance\op@count@ii by2 + \op@search@subexpr{\the\op@count@ii}{\the\op@count@v}% \fi \fi \endgroup } \def\op@search@term#1#2{% \begingroup - \count@i=#1\relax - \count@v=#2\relax - \ifnum\count@i=\count@v + \op@count@i=#1\relax + \op@count@v=#2\relax + \ifnum\op@count@i=\op@count@v \op@token@use{#1}% \else - \count@iii=\count@v - \count@iv=\count@i - \advance\count@iv by-1 - \count@ii=0\relax + \op@count@iii=\op@count@v + \op@count@iv=\op@count@i + \advance\op@count@iv by-1 + \op@count@ii=0\relax \loop - \ifnum\count@iii>\count@iv\relax - \expandafter\ifx\csname OP@token\the\count@iii\endcsname + \ifnum\op@count@iii>\op@count@iv\relax + \expandafter\ifx\csname OP@token\the\op@count@iii\endcsname \op@string@rpar\relax \advance\op@parenthesis by1 \fi - \expandafter\ifx\csname OP@token\the\count@iii\endcsname + \expandafter\ifx\csname OP@token\the\op@count@iii\endcsname \op@string@lpar\relax \advance\op@parenthesis by-1 \fi - \expandafter\ifx\csname OP@token\the\count@iii\endcsname + \expandafter\ifx\csname OP@token\the\op@count@iii\endcsname \op@string@add\relax \ifnum\op@parenthesis=0 - \count@ii=\count@iii\relax - \count@iii=0 + \op@count@ii=\op@count@iii\relax + \op@count@iii=0 \fi \fi - \expandafter\ifx\csname OP@token\the\count@iii\endcsname + \expandafter\ifx\csname OP@token\the\op@count@iii\endcsname \op@string@sub\relax \ifnum\op@parenthesis=0 - \count@ii=\count@iii\relax - \count@iii=0 + \op@count@ii=\op@count@iii\relax + \op@count@iii=0 \fi \fi - \advance\count@iii by-1 + \advance\op@count@iii by-1 \repeat - \ifnum\count@ii=0\relax + \ifnum\op@count@ii=0\relax \ifnum\op@parenthesis=0 - \op@search@factor{\the\count@i}{\the\count@v}% + \op@search@factor{\the\op@count@i}{\the\op@count@v}% \else \op@error{Unbalanced parenthesis in expression}% {Error between tokens #1 and #2}% \fi \else - \advance\count@ii by-1 - \op@search@term{\the\count@i}{\the\count@ii}% - \advance\count@ii by2 - \op@search@term{\the\count@ii}{\the\count@v}% - \advance\count@ii by-1 - \op@token@use{\the\count@ii}% + \advance\op@count@ii by-1 + \op@search@term{\the\op@count@i}{\the\op@count@ii}% + \advance\op@count@ii by2 + \op@search@term{\the\op@count@ii}{\the\op@count@v}% + \advance\op@count@ii by-1 + \op@token@use{\the\op@count@ii}% \fi \fi \endgroup } \def\op@search@factor#1#2{% \begingroup - \count@i=#1\relax - \count@v=#2\relax - \ifnum\count@i=\count@v + \op@count@i=#1\relax + \op@count@v=#2\relax + \ifnum\op@count@i=\op@count@v \op@token@use{#1}% \else - \count@iii=\count@v - \count@iv=\count@i - \advance\count@iv by-1 - \count@ii=0 + \op@count@iii=\op@count@v + \op@count@iv=\op@count@i + \advance\op@count@iv by-1 + \op@count@ii=0 \loop - \ifnum\count@iii>\count@iv - \expandafter\ifx\csname OP@token\the\count@iii\endcsname + \ifnum\op@count@iii>\op@count@iv + \expandafter\ifx\csname OP@token\the\op@count@iii\endcsname \op@string@rpar\relax \advance\op@parenthesis by1 \fi - \expandafter\ifx\csname OP@token\the\count@iii\endcsname + \expandafter\ifx\csname OP@token\the\op@count@iii\endcsname \op@string@lpar\relax \advance\op@parenthesis by-1 \fi - \expandafter\ifx\csname OP@token\the\count@iii\endcsname + \expandafter\ifx\csname OP@token\the\op@count@iii\endcsname \op@string@mul\relax \ifnum\op@parenthesis=0 - \count@ii=\count@iii\relax - \count@iii=0 + \op@count@ii=\op@count@iii\relax + \op@count@iii=0 \fi \fi - \expandafter\ifx\csname OP@token\the\count@iii\endcsname + \expandafter\ifx\csname OP@token\the\op@count@iii\endcsname \op@string@div\relax \ifnum\op@parenthesis=0 - \count@ii=\count@iii\relax - \count@iii=0 + \op@count@ii=\op@count@iii\relax + \op@count@iii=0 \fi \fi - \expandafter\ifx\csname OP@token\the\count@iii\endcsname + \expandafter\ifx\csname OP@token\the\op@count@iii\endcsname \op@string@idiv\relax \ifnum\op@parenthesis=0 - \count@ii=\count@iii\relax - \count@iii=0 + \op@count@ii=\op@count@iii\relax + \op@count@iii=0 \fi \fi - \advance\count@iii by-1 + \advance\op@count@iii by-1 \repeat - \ifnum\count@ii=0\relax + \ifnum\op@count@ii=0\relax \ifnum\op@parenthesis=0 - \op@search@power{\the\count@i}{\the\count@v}% + \op@search@power{\the\op@count@i}{\the\op@count@v}% \else \op@error{Unbalanced parenthesis in expression}% {Error between tokens #1 and #2}% \fi \else - \advance\count@ii by-1 - \op@search@factor{\the\count@i}{\the\count@ii}% - \advance\count@ii by2 - \op@search@factor{\the\count@ii}{\the\count@v}% - \advance\count@ii by-1 - \op@token@use{\the\count@ii}% + \advance\op@count@ii by-1 + \op@search@factor{\the\op@count@i}{\the\op@count@ii}% + \advance\op@count@ii by2 + \op@search@factor{\the\op@count@ii}{\the\op@count@v}% + \advance\op@count@ii by-1 + \op@token@use{\the\op@count@ii}% \fi \fi \endgroup } \def\op@search@power#1#2{% \begingroup - \count@i=#1\relax - \count@v=#2\relax - \ifnum\count@i=\count@v + \op@count@i=#1\relax + \op@count@v=#2\relax + \ifnum\op@count@i=\op@count@v \op@token@use{#1}% \else - \count@iii=\count@v - \count@iv=\count@i - \advance\count@iv by-1 - \count@ii=0 + \op@count@iii=\op@count@v + \op@count@iv=\op@count@i + \advance\op@count@iv by-1 + \op@count@ii=0 \loop - \ifnum\count@iii>\count@iv - \expandafter\ifx\csname OP@token\the\count@iii\endcsname + \ifnum\op@count@iii>\op@count@iv + \expandafter\ifx\csname OP@token\the\op@count@iii\endcsname \op@string@rpar\relax \advance\op@parenthesis by1 \fi - \expandafter\ifx\csname OP@token\the\count@iii\endcsname + \expandafter\ifx\csname OP@token\the\op@count@iii\endcsname \op@string@lpar\relax \advance\op@parenthesis by-1 \fi - \expandafter\ifx\csname OP@token\the\count@iii\endcsname + \expandafter\ifx\csname OP@token\the\op@count@iii\endcsname \op@string@power\relax \ifnum\op@parenthesis=0 - \count@ii=\count@iii\relax - \count@iii=0 + \op@count@ii=\op@count@iii\relax + \op@count@iii=0 \fi \fi - \advance\count@iii by-1 + \advance\op@count@iii by-1 \repeat - \ifnum\count@ii=0\relax + \ifnum\op@count@ii=0\relax \ifnum\op@parenthesis=0 - \op@search@primary{\the\count@i}{\the\count@v}% + \op@search@primary{\the\op@count@i}{\the\op@count@v}% \else \op@error{Unbalanced parenthesis in expression}% {Error between tokens #1 and #2}% \fi \else - \advance\count@ii by-1 - \op@search@power{\the\count@i}{\the\count@ii}% - \advance\count@ii by2 - \op@search@power{\the\count@ii}{\the\count@v}% - \advance\count@ii by-1 - \op@token@use{\the\count@ii}% + \advance\op@count@ii by-1 + \op@search@power{\the\op@count@i}{\the\op@count@ii}% + \advance\op@count@ii by2 + \op@search@power{\the\op@count@ii}{\the\op@count@v}% + \advance\op@count@ii by-1 + \op@token@use{\the\op@count@ii}% \fi \fi \endgroup } \def\op@search@primary#1#2{% \begingroup - \count@i=#1\relax - \count@v=#2\relax - \ifnum\count@i=\count@v + \op@count@i=#1\relax + \op@count@v=#2\relax + \ifnum\op@count@i=\op@count@v \op@token@use{#1}% \else \expandafter\ifx\csname OP@token#1\endcsname\op@string@abs - \advance\count@i by1 - \op@search@primary{\the\count@i}{\the\count@v}% - \advance\count@i by-1 - \op@token@use{\the\count@i}% + \advance\op@count@i by1 + \op@search@primary{\the\op@count@i}{\the\op@count@v}% + \advance\op@count@i by-1 + \op@token@use{\the\op@count@i}% \fi \expandafter\ifx\csname OP@token#1\endcsname\op@string@ceil - \advance\count@i by1 - \op@search@primary{\the\count@i}{\the\count@v}% - \advance\count@i by-1 - \op@token@use{\the\count@i}% + \advance\op@count@i by1 + \op@search@primary{\the\op@count@i}{\the\op@count@v}% + \advance\op@count@i by-1 + \op@token@use{\the\op@count@i}% \fi \expandafter\ifx\csname OP@token#1\endcsname\op@string@decimal - \advance\count@i by1 - \op@search@primary{\the\count@i}{\the\count@v}% - \advance\count@i by-1 - \op@token@use{\the\count@i}% + \advance\op@count@i by1 + \op@search@primary{\the\op@count@i}{\the\op@count@v}% + \advance\op@count@i by-1 + \op@token@use{\the\op@count@i}% \fi \expandafter\ifx\csname OP@token#1\endcsname\op@string@floor - \advance\count@i by1 - \op@search@primary{\the\count@i}{\the\count@v}% - \advance\count@i by-1 - \op@token@use{\the\count@i}% + \advance\op@count@i by1 + \op@search@primary{\the\op@count@i}{\the\op@count@v}% + \advance\op@count@i by-1 + \op@token@use{\the\op@count@i}% \fi \expandafter\ifx\csname OP@token#1\endcsname\op@string@integer - \advance\count@i by1 - \op@search@primary{\the\count@i}{\the\count@v}% - \advance\count@i by-1 - \op@token@use{\the\count@i}% + \advance\op@count@i by1 + \op@search@primary{\the\op@count@i}{\the\op@count@v}% + \advance\op@count@i by-1 + \op@token@use{\the\op@count@i}% \fi \expandafter\ifx\csname OP@token#1\endcsname\op@string@gcd - \advance\count@i by1 - \op@search@primary{\the\count@i}{\the\count@v}% - \advance\count@i by-1 - \op@token@use{\the\count@i}% + \advance\op@count@i by1 + \op@search@primary{\the\op@count@i}{\the\op@count@v}% + \advance\op@count@i by-1 + \op@token@use{\the\op@count@i}% \fi \expandafter\ifx\csname OP@token#1\endcsname\op@string@mod - \advance\count@i by1 - \op@search@primary{\the\count@i}{\the\count@v}% - \advance\count@i by-1 - \op@token@use{\the\count@i}% + \advance\op@count@i by1 + \op@search@primary{\the\op@count@i}{\the\op@count@v}% + \advance\op@count@i by-1 + \op@token@use{\the\op@count@i}% \fi \expandafter\ifx\csname OP@token#1\endcsname\op@string@neg - \advance\count@i by1 - \op@search@primary{\the\count@i}{\the\count@v}% - \advance\count@i by-1 - \op@token@use{\the\count@i}% + \advance\op@count@i by1 + \op@search@primary{\the\op@count@i}{\the\op@count@v}% + \advance\op@count@i by-1 + \op@token@use{\the\op@count@i}% \fi \expandafter\ifx\csname OP@token#1\endcsname\op@string@rest - \advance\count@i by1 - \op@search@primary{\the\count@i}{\the\count@v}% - \advance\count@i by-1 - \op@token@use{\the\count@i}% + \advance\op@count@i by1 + \op@search@primary{\the\op@count@i}{\the\op@count@v}% + \advance\op@count@i by-1 + \op@token@use{\the\op@count@i}% \fi \expandafter\ifx\csname OP@token#1\endcsname\op@string@round - \advance\count@i by1 - \op@search@primary{\the\count@i}{\the\count@v}% - \advance\count@i by-1 - \op@token@use{\the\count@i}% + \advance\op@count@i by1 + \op@search@primary{\the\op@count@i}{\the\op@count@v}% + \advance\op@count@i by-1 + \op@token@use{\the\op@count@i}% \fi \expandafter\ifx\csname OP@token#1\endcsname \op@string@lpar\relax \expandafter\ifx\csname OP@token#2\endcsname \op@string@rpar\relax - \advance\count@i by1 - \advance\count@v by-1 - \op@search@subexpr{\the\count@i}{\the\count@v}% + \advance\op@count@i by1 + \advance\op@count@v by-1 + \op@search@subexpr{\the\op@count@i}{\the\op@count@v}% \else \op@error{Garbage after parenthesis}% {Error between tokens #1 and #2}% @@ -3905,32 +3993,32 @@ \op@isrparenthesisfalse \op@isspacefalse \op@isotherfalse - \count255=`#1\relax - \ifnum\count255=\op@plus \relax + \count@=`#1\relax + \ifnum\count@=\op@plus \relax \op@isplustrue - \else \ifnum\count255=\op@minus \relax + \else \ifnum\count@=\op@minus \relax \op@isminustrue - \else \ifnum\count255=\op@multiply \relax + \else \ifnum\count@=\op@multiply \relax \op@ismultiplytrue - \else \ifnum\count255=\op@divide \relax + \else \ifnum\count@=\op@divide \relax \op@isdividetrue - \else \ifnum\count255=\op@idivide \relax + \else \ifnum\count@=\op@idivide \relax \op@isidividetrue - \else \ifnum\count255=\op@pow \relax + \else \ifnum\count@=\op@pow \relax \op@ispowertrue - \else \ifnum\count255=\op@dot \relax + \else \ifnum\count@=\op@dot \relax \op@isdottrue - \else \ifnum\count255=\op@comma \relax + \else \ifnum\count@=\op@comma \relax \op@iscommatrue - \else \ifnum\count255=\op@lparenthesis \relax + \else \ifnum\count@=\op@lparenthesis \relax \op@islparenthesistrue - \else \ifnum\count255=\op@rparenthesis \relax + \else \ifnum\count@=\op@rparenthesis \relax \op@isrparenthesistrue - \else \ifnum\count255=\op@space \relax + \else \ifnum\count@=\op@space \relax \op@isspacetrue - \else \ifnum\count255<\op@numbegin \relax + \else \ifnum\count@<\op@numbegin \relax \op@isothertrue - \else \ifnum\count255>\op@numend \relax + \else \ifnum\count@>\op@numend \relax \op@isothertrue \else \op@isdigittrue \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi -- cgit v1.2.3