Sommaire
Introduction
La lecture de ce journal 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/.
L'expression à évaluer peut être algébrique (1 + 2 / 3
) ou RPN (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
etX
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 <nombre> -
.
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
(voiretarget=win32
outarget=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.
- en lançant la compilation du
À 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
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/).
JRE (Java).
GitHub : http://github.com/epeios-q37/rncq-java
il faut au préalable récupérer le wrapper Java, 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
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.
# Typo ?
Posté par liberforce (site web personnel) . Évalué à 5. Dernière modification le 28 septembre 2017 à 17:55.
Je ne suis pas allé au bout, mais j'ai tiqué quand j'ai lu ça:
(1 + 2 / 3) ou RPN (1 2 + 3 /)
en RPN,
1 2 + 3 /
ça fait 3/3 = 1Tandis que d'après les règles de priorité des opérateurs,
1 + 2 / 3
, c'est1 + (2 / 3)
, soit 1,666666…Un oubli de parenthèses ?
Edit:
C'est un peu gênant pour un outil destiné à faire du calcul ? Bon, après si c'est en développement… Je te conseille tout de même de ne pas mettre le mode algébrique en avant, ou le désactiver tant que la gestion standard n'est pas gérée, ça peut être source de confusion.
[^] # Re: Typo ?
Posté par SpaceFox (site web personnel, Mastodon) . Évalué à 2. Dernière modification le 28 septembre 2017 à 18:55.
En fait il n'y a pas de parenthèses ou de priorité à reconnaitre, puisque tout l'intérêt de la RPN est justement qu'il n'y a plus besoin de gérer de parenthèses ou de priorité : tous les calculs sont faits instantanément.
Mais c'est à l'utilisateur de rentrer le calcul dans le bon ordre : pour faire le calcul
1 + 2 / 3
en respectant la priorité du calcul écrit ainsi, il faut taper en RPN :2 3 / 1 +
. Mais une erreur sur ce point n'est plus une erreur de l'interpréteur, c'est une erreur d'ICC :)La connaissance libre : https://zestedesavoir.com
[^] # Re: Typo ?
Posté par Colin Pitrat (site web personnel) . Évalué à 3.
Il parlait de la notation algébrique
[^] # Re: Typo ?
Posté par flavien75 . Évalué à 3.
Je cite le journal :
Tu n'es effectivement pas allé jusqu'au bout.
Les vrais naviguent en -42
# Java
Posté par ylsul . Évalué à 1.
J'ai peut-être lu un peu vite, mais en java le format de distribution binaire est le jar.
Il existe des dépôts comme ceux de Maven, mais je ne sais pas comment on ajoute des paquets dedans.
# Existant ?
Posté par Matthieu Moy (site web personnel) . Évalué à 3.
Dans le même genre, il y a libgmp :
https://gmplib.org/
[^] # Re: Existant ?
Posté par Guillaum (site web personnel) . Évalué à 5.
Sachant que libgmp est massivement utilisée, c'est au moins le support des "bigint" et "rational" en python et Haskell, sans doute aussi dans d'autres langages.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.