URL: https://linuxfr.org/users/epeios/journaux/calculs-numeriques-en-precision-absolue Title: Calculs numériques en précision absolue. Authors: Claude SIMON Date: 2017年09月28日T16:27:38+02:00 License: CC By-SA Tags: calcul, rpn, rationnels, ligne_de_commande, nodejs, java et c++ Score: 13 # Introduction La lecture de ce [journal](https://linuxfr.org/users/niconico/journaux/sql-decimal-vs-double) m'a remémoré une bibliothèque de calcul numérique que j'ai développée et qui pourrait peut-être en intéresser quelques-uns ici. J'ai rarement utilisé les nombres flottants à cause de leur précision limitée, et les entiers se sont parfois révélés inadaptés de par leur intervalles limités. Aussi ai-je développé une bibliothèque de gestion d'entiers dynamiques, et, en m'appuyant sur cette dernière, une bibliothèque de gestion de nombres rationnels qui prend en charge les 4 opérations mathématiques de base avec une précision absolue. Les logiciels que je présente ici ne sont, pour l'instant, que capable de calculer le résultat d'une chaîne de caractères contenant une expression numérique. Ce calcul peut se réaliser à l'aide d'un utilitaire en ligne de commande, d'un *addon* *Node.js*, ou d'un composant *Java*. Il est possible d'essayer cette bibliothèque en ligne, pour peu que l'on ai quelques rudiments en *Javascript* et le navigateur adéquat, en se rendant à cette adresse : [http://npm.runkit.com/rncq/](http://q37.info/runkit/rncq/). L'expression à évaluer peut être algébrique (`1 + 2 / 3`) ou *[RPN](http://q37.info/s/x/RPN_fr/)* (`1 2 + 3 /`). La version en ligne de commande propose en outre deux options : - `--to-float` qui convertit le résultat final en *float*, - `--use-float` qui réalise le calcul à l'aide du type *float*. La mise en œuvre d'une de ces deux options peut avoir des résultats inattendus, de par la précision limité du type *float*, mais aussi parce que les calculs peuvent aboutir à des nombres qui dépassent largement les capacités du type *float*. # Les expressions ## Formats Une expression peut être exprimée au format algébrique (`1 + 2 * 3`) ou *RPN* (`1 2 3 * +`). Elle peut contenir un nombre décimal (le séparateur est `.` ou `,`), auquel cas il est convertit en sa fraction équivalente. Par exemple, `12.345` est convertit en `2469/200` (qui est égal à `12345/1000`). Les opérateurs reconnus sont : - `+` pour l'addition, - `-` pour la soustraction, - `*`, `x`et `X` pour la multiplication, - `/` et `:` pour la division. Lorsque l'expression à évaluer est un argument de ligne de commande, il faut prendre garde aux opérateurs utilisés. Par exemple, l'opérateur de multiplication usuel (`*`) peut poser problème sous système *POSIX*, car l'interpréteur le remplace par une liste de fichiers ; il faut donc l'échapper (`\*`), mettre l'expression entre guillemets ou utiliser l'un des symboles alternatifs (`x`ou `X`). De la même manière, si l'expression contient des espaces, il faut mettre toute l'expression entre guillemets, pour qu'elle soit comprise par le programme comme un seul est unique argument. ## Notation algébrique C'est la notation usuelle, à savoir, par exemple, `1 + 2 * 3`. Les parenthèses ne sont actuellement pas reconnues, et la priorité des opérateurs n'est pas prise en compte (`1+2*3` donne `9`, et non pas `7`). les `-` et `+`unaires sont, eux, reconnus. ## Notation *RPN* C'est la notation dans laquelle on donne d'abord les arguments d'une opération avant de préciser l'opérateur qui doit être appliqué. Ainsi, l'équivalent de l'expression algébrique `(1 + 2) * 3` sera `1 2 + 3 *`(on voit que le format *RPN* permet de se passer de parenthèses). Le `-` unaire n'est actuellement pas implémenté, aussi, pour entrer un nombre négatif, il convient d'écrire `0 -`. # Installation et utilisation ## Généralités Mis à part sous *Windows*, il faut qu'un environnement de compilation *C++* soit installé. Les différents paquets sont compilés : - sous environnement *POSIX* (y compris *macOS* et *Cygwin*), en lançant la commande `make` à la racine du *package*, - sous *Windows*, - en lançant la compilation du `.vcxproj` dans *Visual Studio*, - sous *Cygwin*, voir ci-dessus (environnement *POSIX*) , sachant que : - par défaut, le binaire produit utilisera l'*API* *Cygwin*, - en passant l'argument `target=win` (voire `target=win32` ou `target=win64` pour produire explicitement une version *IA-32* ou *AMD64* du binaire), si la version adéquate de *mingw* est installée, on obtient un binaire utilisant l'*API* Windows. À noter que les binaires *Windows* d'un paquet sont directement disponibles dans la section *releases* du *repository* *GitHub* dudit paquet. Si le paquet est directement lié à un *framework* tiers, il est possible que le *framewok* en question impose la manière dont le paquet doit être compilé. Il faudra alors voir la documentation dudit *framework*. ## *Node.js* *GitHub* : [http://github.com/epeios-q37/rncq-node](http://q37.info/github/rncq-node) [![NPM](https://nodei.co/npm/rncq.png)](https://nodei.co/npm/rncq/) Le composant étant disponible sur *NPM*, il suffit de lancer `npm install rncq`. Excepté sous *Windows*, il faut qu'un environnement de compilation *C++* soit installé. Une fois installé, on peut lancer un test avec `npm explore rncq -- node test.js`, avec éventuellement, comme argument, une expression à évaluer. Par défaut, cette expression doit être en notation algébrique, mais en modifiant le fichier `node_modules/rncq/test.js`, on peut basculer en notation *RPN* (voir les commentaires dans le fichier en question). Pour rappel, la version *Node.js* peut être testée en ligne sur *Runkit* ([http://npm.runkit.com/rncq/](http://q37.info/runkit/rncq/)). ## *JRE* (*Java*). *GitHub* : [http://github.com/epeios-q37/rncq-java](http://q37.info/github/rncq-java) il faut au préalable récupérer le [*wrapper* *Java*](http://q37.info/github/jreq/), et lancer la compilation comme indiqué ci-dessus. Il faut que le *Java Development Kit* soit installé. Une fois le binaire compilé, il faudra le placer, ainsi que les fichiers `jreq.xcfg`et `jreq.xlcl`, à la racine du paquet *rncq-java* (les fichiers `.java` et `.class` ne sont pas nécessaires). Une fois le paquet *rncq-java* compilé (et les fichiers du *wrapper* mis en place), on peut lancer un test avec `java RNCqTest`, et éventuellement passer une expression numérique comme argument. On peut basculer en mode *RPN* en modifiant le fichier (qu'il faudra alors recompiler) `RNCq.java` (voir les commentaires dans ce fichier). ## Ligne de commande *GitHub* : [http://github.com/epeios-q37/rncq-cli](http://q37.info/github/rncq-cli) Après compilation (voir ci-dessus), il suffit de lancer `rncq` avec l'expression numérique à évaluer. Par défaut, l'expression doit être au format algébrique, mais avec l'option `--rpn`, on peut saisir une expression au format *RPN*. `rncq --help` permet d'afficher la liste des option disponibles. # Évolution Je projette, pour les prochaines versions, d'exposer, afin de pouvoir y accéder directement, les différentes fonctions permettant de réaliser les calculs. Ceci dit, pour *Node.js*, je ne vois pas encore trop à quoi devrait ressembler l'*API* pour qu'elle soit non bloquante (s'il y en a qui ont des idées à ce propos...). Il est également possible que je développe une version pour *PHP*, voire d'autres environnements d'exécution. Je voudrais également améliorer le procédure d'installation, notamment pour la version *Java*, mais il n'existe (ou je n'ai pas trouvé) l'équivalent de *NPM* pour *Java*, donc je ne sais, pour l'instant, pas encore comment faire.

AltStyle によって変換されたページ (->オリジナル) /