bc , pour basic calculator , est « un langage de calculatrice de précision arbitraire » avec une syntaxe similaire au langage de programmation C. bc est généralement utilisé soit comme langage de script mathématique, soit comme shell mathématique interactif.
Aperçu
Une utilisation interactive typique consiste à taper la commande bcsur une invite de commande Unix et à entrer une expression mathématique, telle que , après quoi(1 + 3) * 28sera affiché. Bien que bc puisse fonctionner avec une précision arbitraire, il utilise en fait par défaut zéro chiffre après la virgule décimale, de sorte que l'expression 2/3donne0(les résultats sont tronqués et non arrondis). Cela peut surprendre les nouveaux utilisateurs de bc qui ne sont pas au courant de ce fait. L' -loption bc définit l' échelle par défaut (chiffres après la virgule décimale) à 20 et ajoute plusieurs fonctions mathématiques supplémentaires au langage.
Histoire
bc est apparu pour la première fois dans la version 6 d'Unix en 1975. Il a été écrit par Lorinda Cherry de Bell Labs comme une interface pour dc , une calculatrice de précision arbitraire écrite par Robert Morris et Cherry. dc effectuait des calculs de précision arbitraire spécifiés en notation polonaise inversée . bc fournissait une interface de langage de programmation conventionnelle avec la même capacité via un simple compilateur (un seul fichier source yacc comprenant quelques centaines de lignes de code), qui convertissait une syntaxe de type C en notation dc et transmettait les résultats via dc.
En 1991, POSIX a rigoureusement défini et standardisé bc. Quatre implémentations de cette norme survivent aujourd'hui : la première est l'implémentation Unix traditionnelle, une interface pour dc, qui survit dans les systèmes Unix et Plan 9. La deuxième est le logiciel libre GNU bc, publié pour la première fois en 1991 par Philip A. Nelson. L'implémentation GNU a de nombreuses extensions au-delà de la norme POSIX et n'est plus une interface pour dc (c'est un interpréteur de bytecode ). La troisième est une réimplémentation par OpenBSD en 2003. La quatrième est une implémentation indépendante par Gavin Howard qui est incluse dans Android (système d'exploitation) [ FreeBSD à partir de la version 13.3-RELEASE et macOS à partir de la version 13.0
Implémentations
POSIX bc
Le langage bc standardisé POSIX est traditionnellement écrit sous la forme d'un programme dans le langage de programmation DC pour fournir un niveau d'accès plus élevé aux fonctionnalités du langage DC sans les complexités de la syntaxe concise de DC.
Sous cette forme, le langage bc contient des noms de variables à une seule lettre , de tableaux et de fonctions et la plupart des opérateurs arithmétiques standard, ainsi que les constructions de contrôle de flux familières ( , et ) de C. Contrairement à C, une clause ne peut pas être suivie d'un . if(cond)...while(cond)...for(init;cond;inc)...ifelse
Les fonctions sont définies à l'aide d'un definemot-clé et les valeurs sont renvoyées à partir de celles-ci à l'aide d'un returnsuivi de la valeur de retour entre parenthèses. Le automot-clé (facultatif en C) est utilisé pour déclarer une variable comme locale à une fonction.
Tous les nombres et contenus de variables sont des nombres de précision arbitraire dont la précision (en décimales) est déterminée par la scalevariable globale.
La base numérique des constantes d'entrée (en mode interactif), de sortie et de programme peut être spécifiée en définissant les variables réservées ibase(base d'entrée) et obase(base de sortie).
La sortie est générée en n'attribuant délibérément pas le résultat d'un calcul à une variable.
Des commentaires peuvent être ajoutés au code bc en utilisant les symboles C /*et */(commentaire de début et de fin).
Opérateurs mathématiques
Exactement comme C
Les opérateurs POSIX bc suivants se comportent exactement comme leurs homologues C :
+ - * / += -= *= /= ++ -- < > == != <= >= ( ) [ ] { }
Similaire à C
Les opérateurs de module% et %=se comportent exactement comme leurs homologues C uniquement lorsque la scalevariable globale est définie sur 0, c'est-à-dire que tous les calculs sont uniquement des entiers. Sinon, le calcul est effectué avec l'échelle appropriée. a%best défini comme a-(a/b)*b. Exemples :
$ bc bc 1.06 Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc. Il s'agit d'un logiciel libre sans AUCUNE GARANTIE. Pour plus de détails, saisissez « garantie ». scale=0; 5%3 2 scale=1; 5%3 .2 scale=20; 5%3 .000000000000000000002
En conflit avec C
Les opérateurs
^ ^=
ressemblent superficiellement aux opérateurs exclusifs binaires C , mais sont en fait les opérateurs d'exponentiation entière bc.
Il convient de noter en particulier que l’utilisation de l’ ^opérateur avec des nombres négatifs ne suit pas la priorité des opérateurs C. -2^2donne la réponse de 4 sous bc plutôt que −4.
Opérateurs « manquants » par rapport à C
Les opérateurs bit à bit , booléens et conditionnels :
& | ^ && || &= |= ^= &&= ||= << >> <<= >>= ?:
ne sont pas disponibles dans POSIX bc.
Fonctions intégrées
La sqrt()fonction de calcul des racines carrées est la seule fonction mathématique intégrée de POSIX bc. D'autres fonctions sont disponibles dans une bibliothèque standard externe.
La scale()fonction permettant de déterminer la précision (comme avec la scalevariable) de son argument et la length()fonction permettant de déterminer le nombre de chiffres décimaux significatifs dans son argument sont également intégrées.
Fonctions de la bibliothèque standard
La bibliothèque mathématique standard de bc (définie avec l' option -l ) contient des fonctions pour calculer le sinus , le cosinus , l'arctangente , le logarithme naturel , la fonction exponentielle et la fonction de Bessel à deux paramètres J. La plupart des fonctions mathématiques standard (y compris les autres fonctions trigonométriques inverses) peuvent être construites à l'aide de celles-ci. Voir les liens externes pour les implémentations de nombreuses autres fonctions.
L' option -l modifie l'échelle à 20, , de sorte que des éléments tels que le modulo peuvent fonctionner de manière inattendue. Par exemple, si vous écrivez bc -lpuis, la commande print 3%2renvoie 0. Mais si vous écrivez scale=0après bc -lpuis, la commande print 3%2renvoie 1.
Plan 9 avant J.C.
Le plan 9 bc est identique au POSIX bc mais avec une printinstruction supplémentaire.
GNU bc
GNU bc dérive de la norme POSIX et inclut de nombreuses extensions. Il est entièrement distinct des implémentations basées sur DC de la norme POSIX et est plutôt écrit en C. Néanmoins, il est entièrement rétrocompatible car tous les programmes POSIX bc s'exécuteront sans modification en tant que programmes GNU bc.
Les variables, tableaux et noms de fonctions GNU bc peuvent contenir plus d'un caractère, d'autres opérateurs ont été inclus à partir de C et, notamment, une ifclause peut être suivie d'un else.
La sortie est obtenue soit en n'attribuant délibérément pas le résultat d'un calcul à une variable (à la manière POSIX), soit en utilisant l' printinstruction ajoutée.
De plus, une readinstruction permet la saisie interactive d’un nombre dans un calcul en cours.
En plus des commentaires de style C, un #caractère fera que tout ce qui le suit jusqu'à la prochaine nouvelle ligne sera ignoré.
La valeur du dernier calcul est toujours stockée dans la variable intégrée supplémentaire last.
Opérateurs supplémentaires
Les opérateurs logiques suivants s'ajoutent à ceux de POSIX bc :
&& || !
Elles peuvent être utilisées dans des instructions conditionnelles (par exemple dans une ifinstruction). Notez cependant qu'il n'existe toujours pas d'opérations d'affectation ou au niveau du bit équivalentes.
Fonctions
Toutes les fonctions disponibles dans GNU bc sont héritées de POSIX. Aucune autre fonction n'est fournie en standard avec la distribution GNU.
Exemple de code
Étant donné que l'opérateur bc ^n'autorise qu'une puissance entière à sa droite, l'une des premières fonctions qu'un utilisateur bc peut écrire est une fonction puissance avec un exposant à virgule flottante. Les deux éléments ci-dessous supposent que la bibliothèque standard a été incluse :
Une fonction « power » dans POSIX bc
/* Une fonction pour renvoyer la partie entière de x */ define i ( x ) { auto s s = échelle échelle = 0 x /= 1 /* arrondir x vers le bas */ échelle = s retour ( x ) } /* Utiliser le fait que x^y == e^(y*log(x)) */ define p ( x , y ) { if ( y == i ( y )) { return ( x ^ y ) } return ( e ( y * l ( x ) ) ) }
Calcul de π à 10 000 chiffres
Calculez pi en utilisant la fonction arctangente intégrée, a() :
$ bc -lq scale=10000 4*a(1) # L'atan de 1 est de 45 degrés, soit pi/4 en radians. # Ce calcul peut prendre plusieurs minutes .
Une fonction C traduite
Comme la syntaxe de bc est similaire à celle de C , les fonctions numériques publiées écrites en C peuvent souvent être traduites en bc assez facilement, ce qui fournit immédiatement la précision arbitraire de bc. Par exemple, dans le Journal of Statistical Software (juillet 2004, volume 11, numéro 5), George Marsaglia a publié le code C suivant pour la distribution normale cumulative :
double Phi ( double x ) { long double s = x , t = 0 , b = x , q = x * x , i = 1 ; tandis que ( s != t ) s = ( t = s ) + ( b *= q / ( i += 2 )); renvoie .5 + s * exp ( -.5 * q -.91893853320467274178L ); }
Avec quelques modifications nécessaires pour s'adapter à la syntaxe différente de bc, et en notant que la constante « 0,9189... » est en fait log(2*PI)/2, cela peut être traduit par le code GNU bc suivant :
définir phi ( x ) { auto s , t , b , q , i , const s = x ; t = 0 ; b = x ; q = x * x ; i = 1 tant que ( s != t ) s = ( t = s ) + ( b *= q / ( i += 2 )) const = 0,5 * l ( 8 * a ( 1 )) # 0,91893 ... renvoie ,5 + s * e ( - , 5 * q - const ) }
Utilisation de bc dans les scripts shell
bc peut être utilisé de manière non interactive, avec une entrée via un tube . Ceci est utile dans les scripts shell . Par exemple :
$ résultat = $( echo "échelle=2; 5 * 7 /3;" | bc ) $ echo $résultat 11.66
En revanche, notez que le shell bash n'effectue que des opérations arithmétiques sur des nombres entiers, par exemple :
$ résultat = $(( 5 * 7 / 3 )) $ echo $résultat 11
On peut également utiliser l' idiome here-string (dans bash, ksh, csh) :
$ bc -l <<< "5*7/3" 11,66666666666666666666