bc - manuel de référence, options, exemples de commandes


NOM

bc - Un langage de calcul de précision arbitraire

SYNTAXE

bc [ -hlwsqv ] [options-longues] [ fichier ... ]

DESCRIPTION

bc est un langage qui prend en charge les nombres de précision arbitraire avec une exécution interactive des instructions. Il existe certaines similitudes dans la syntaxe avec le langage de programmation C. Une bibliothèque mathématique standard est disponible par option de ligne de commande. Si nécessaire, la bibliothèque mathématique est définie avant le traitement des fichiers. bc commence par traiter le code de tous les fichiers répertoriés sur la ligne de commande dans l'ordre indiqué. Une fois tous les fichiers traités, bc lit à partir de l'entrée standard. Tout le code est exécuté au fur et à mesure qu'il est lu. (Si un fichier contient une commande pour arrêter le processeur, bc ne lira jamais à partir de l'entrée standard.)

Cette version de bc contient plusieurs extensions au-delà des implémentations bc traditionnelles et du projet de norme POSIX. Les options de ligne de commande peuvent entraîner l'affichage d'un avertissement ou le rejet de ces extensions. Ce document décrit le langage accepté par ce processeur. Les extensions seront identifiées comme telles.

OPTIONS

-h, --help

Imprimez l'utilisation et quittez.

-i, --interactive

Forcer le mode interactif.

-l, --mathlib

Définissez la bibliothèque mathématique standard.

-w, --warn

Donner des avertissements pour les extensions à POSIX bc.

-s, --standard

Traite exactement le langage POSIX bc.

-q, --quiet

N'imprimez pas l'accueil normal de GNU bc.

-v, --version

Imprimez le numéro de version et le copyright et quittez.

NOMBRES

L'élément le plus basique de bc est le nombre. Les nombres sont des nombres de précision arbitraire. Cette précision est à la fois dans la partie entière et dans la partie fractionnaire. Tous les nombres sont représentés en interne en décimal et tous les calculs sont effectués en décimal. (Cette version tronque les résultats des opérations de division et de multiplication.) Il existe deux attributs de nombres, la longueur et l'échelle. La longueur est le nombre total de chiffres décimaux utilisés par bc pour représenter un nombre et l'échelle est le nombre total de chiffres décimaux après la virgule. Par exemple:

 .000001 has a length of 6 and scale of 6.
 1935.000 has a length of 7 and a scale of 3.

VARIABLES

Les nombres sont stockés dans deux types de variables, les variables simples et les tableaux. Les variables simples et les variables de tableau sont nommées. Les noms commencent par une lettre suivie d'un nombre quelconque de lettres, de chiffres et de traits de soulignement. Toutes les lettres doivent être en minuscules. (Les noms alphanumériques complets sont une extension. Dans POSIX bc tous les noms sont une seule lettre minuscule.) Le type de variable est clair par le contexte car tous les noms de variables de tableau seront suivis de crochets ( []).

Il existe quatre variables spéciales, scale, ibase, obase, et last. scale définit comment certaines opérations utilisent les chiffres après la virgule décimale. La valeur par défaut de scale est 0. ibase et obase définissent la base de conversion pour les nombres d'entrée et de sortie. La valeur par défaut pour l'entrée et la sortie est la base 10. last (une extension) est une variable qui a la valeur du dernier nombre imprimé. Ceux-ci seront discutés plus en détail le cas échéant. Toutes ces variables peuvent avoir des valeurs qui leur sont assignées ainsi qu'utilisées dans des expressions.

COMMENTAIRES

Les commentaires en bc commencent par les caractères /* et se terminent par les caractères */. Les commentaires peuvent commencer n'importe où et apparaître sous la forme d'un seul espace dans l'entrée. (Ainsi, les commentaires délimitent d'autres éléments d'entrée. Par exemple, un commentaire ne peut pas être trouvé au milieu d'un nom de variable.) Les commentaires incluent toutes les nouvelles lignes (fin de ligne) entre le début et la fin du commentaire.

Pour prendre en charge l'utilisation de scripts pour bc, un commentaire d'une seule ligne a été ajouté en tant qu'extension. Un commentaire sur une seule ligne commence par un caractère # et continue jusqu'à la fin de la ligne suivante. Le caractère de fin de ligne ne fait pas partie du commentaire et est traité normalement.

EXPRESSIONS

Les nombres sont manipulés par des expressions et des instructions. Comme le langage a été conçu pour être interactif, les instructions et les expressions sont exécutées dès que possible. Il n'y a pas de programme "principal". Au lieu de cela, le code est exécuté au fur et à mesure qu'il est rencontré. (Les fonctions, décrites en détail plus loin, sont définies lorsqu'elles sont rencontrées.)

Une expression simple n'est qu'une constante. bc convertit les constantes en nombres décimaux internes en utilisant la base d'entrée actuelle, spécifiée par la variable ibase. (Il y a une exception dans les fonctions.) Les valeurs légales de ibase sont comprises entre 2 et 36. (Les bases supérieures à 16 sont une extension.) Affectation d'une valeur en dehors de cette plage à ibase > donnera une valeur de 2 ou 36. Les nombres saisis peuvent contenir les caractères 0-9 et A-Z. (Remarque : ils doivent être en majuscules. Les lettres minuscules sont des noms de variables.) Les nombres à un chiffre ont toujours la valeur du chiffre, quelle que soit la valeur de ibase. (c'est-à-dire A=10.) Pour les nombres à plusieurs chiffres, bc remplace tous les chiffres d'entrée supérieurs ou égaux à ibase par la valeur de ibase-1. Ainsi, le nombre ZZZ est toujours le plus grand nombre à 3 chiffres de la base d'entrée.

Les expressions complètes sont similaires à de nombreux autres langages de haut niveau. Puisqu'il n'y a qu'un seul type de nombre, il n'y a pas de règles pour mélanger les types. Au lieu de cela, il existe des règles sur l'échelle des expressions. Chaque expression a une échelle. Ceci est dérivé de l'échelle des nombres d'origine, de l'opération effectuée et, dans de nombreux cas, de la valeur de la variable échelle. Les valeurs légales de la variable échelle vont de 0 au nombre maximum représentable par un entier C.

Dans les descriptions suivantes des expressions légales, « expr » fait référence à une expression complète et « var » fait référence à une simple ou une variable de tableau. Une simple variable n'est qu'un

name

et une variable de tableau est spécifiée comme

name[expr]

Sauf indication contraire, l'échelle du résultat est l'échelle maximale des expressions impliquées.

- expr

Le résultat est la négation de l'expression.

++ var

La variable est incrémentée de un et la nouvelle valeur est le résultat de l'expression.

-- var

La variable est décrémentée de un et la nouvelle valeur est le résultat de l'expression.

var ++

Le résultat de l'expression est la valeur de la variable, puis la variable est incrémentée de un.

var --

Le résultat de l'expression est la valeur de la variable, puis la variable est décrémentée de un.

expr + expr

Le résultat de l'expression est la somme des deux expressions.

expr - expr

Le résultat de l'expression est la différence des deux expressions.

expr * expr

Le résultat de l'expression est le produit des deux expressions.

expr / expr

Le résultat de l'expression est le quotient des deux expressions. L'échelle du résultat est la valeur de la variable échelle.

expr % expr

Le résultat de l'expression est le "reste" et il est calculé de la manière suivante. Pour calculer a%b, d'abord a/b est calculé en chiffres à l'échelle. Ce résultat est utilisé pour calculer a-(a/b)*b à l'échelle du maximum de scale+scale(b) et scale(a). Si scale est défini sur zéro et que les deux expressions sont des entiers, cette expression est la fonction de reste entier.

expr ^ expr

Le résultat de l'expression est la valeur de la première élevée à la seconde. La deuxième expression doit être un entier. (Si la deuxième expression n'est pas un entier, un avertissement est généré et l'expression est tronquée pour obtenir une valeur entière.) L'échelle du résultat est échelle si l'exposant est négatif. Si l'exposant est positif, l'échelle du résultat est le minimum de l'échelle de la première expression multiplié par la valeur de l'exposant et le maximum de échelle et l'échelle de la première expression. (par exemple, scale(a^b)=min(scale(a)*b, max( scale, scale(a))).) Il convient de noter que expr^0 renverra toujours la valeur de 1.

( expr )

Cela modifie la priorité standard pour forcer l'évaluation de l'expression.

var = expr

La variable reçoit la valeur de l'expression.

var <op>= expr

Cela équivaut à "var=var expr" à l'exception que la partie "var" n'est évaluée qu'une seule fois. Cela peut faire une différence si "var" est un tableau.

Les expressions relationnelles sont un type spécial d'expression qui évalue toujours à 0 ou 1, 0 si la relation est fausse et 1 si la relation est vraie. Ceux-ci peuvent apparaître dans n'importe quelle expression juridique. (POSIX bc exige que les expressions relationnelles ne soient utilisées que dans les instructions if, while et for et qu'un seul test relationnel puisse y être effectué.) Les opérateurs relationnels sont

expr1 < expr2

Le résultat est 1 si expr1 est strictement inférieur à expr2.

expr1 <= expr2

Le résultat est 1 si expr1 est inférieur ou égal à expr2.

expr1 > expr2

Le résultat est 1 si expr1 est strictement supérieur à expr2.

expr1 >= expr2

Le résultat est 1 si expr1 est supérieur ou égal à expr2.

expr1 == expr2

Le résultat est 1 si expr1 est égal à expr2.

expr1 != expr2

Le résultat est 1 si expr1 n'est pas égal à expr2.

Les opérations booléennes sont également légales. (POSIX bc n'a PAS d'opérations booléennes). Le résultat de toutes les opérations booléennes est 0 et 1 (pour faux et vrai) comme dans les expressions relationnelles. Les opérateurs booléens sont :

!expr

Le résultat est 1 si expr vaut 0.

expr && expr

Le résultat est 1 si les deux expressions sont non nulles.

expr || expr

Le résultat est 1 si l'une des expressions est différente de zéro.

La priorité des expressions est la suivante : (du plus bas au plus élevé)

|| operator, left associative
&& operator, left associative
! operator, nonassociative
Relational operators, left associative
Assignment operator, right associative
+ and - operators, left associative
*, / and % operators, left associative
^ operator, right associative
unary - operator, nonassociative
++ and -- operators, nonassociative

Cette priorité a été choisie pour que les programmes bc conformes à POSIX s'exécutent correctement. Cela entraînera un comportement inhabituel de l'utilisation des opérateurs relationnels et logiques lorsqu'ils sont utilisés avec des expressions d'affectation. Considérez l'expression :

a = 3 < 5

La plupart des programmeurs C supposeraient que cela attribuerait le résultat "3 < 5" (la valeur 1) à la variable "a". Ce que cela fait dans bc est d'attribuer la valeur 3 à la variable "a", puis de comparer 3 à 5. Il est préférable d'utiliser des parenthèses lors de l'utilisation d'opérateurs relationnels et logiques avec les opérateurs d'affectation.

Il existe quelques expressions spéciales supplémentaires fournies dans bc. Celles-ci concernent les fonctions définies par l'utilisateur et les fonctions standard. Ils apparaissent tous sous la forme "nom(paramètres)". Voir la section sur les fonctions pour les fonctions définies par l'utilisateur. Les fonctions standards sont :

length ( expression )

La valeur de la fonction de longueur est le nombre de chiffres significatifs dans l'expression.

read ( )

La fonction de lecture (une extension) lira un nombre à partir de l'entrée standard, quel que soit l'endroit où la fonction se produit. Attention, cela peut poser des problèmes de mélange de données et de programme dans l'entrée standard. La meilleure utilisation de cette fonction est dans un programme écrit précédemment qui nécessite une entrée de l'utilisateur, mais qui n'autorise jamais l'entrée de code de programme par l'utilisateur. La valeur de la fonction de lecture est le nombre lu à partir de l'entrée standard en utilisant la valeur actuelle de la variable ibase pour la base de conversion.

scale ( expression )

La valeur de la fonction d'échelle est le nombre de chiffres après la virgule décimale dans l'expression.

sqrt ( expression )

La valeur de la fonction sqrt est la racine carrée de l'expression. Si l'expression est négative, une erreur d'exécution est générée.

DÉCLARATIONS

Les déclarations (comme dans la plupart des langages algébriques) fournissent le séquencement de l'évaluation des expressions. Dans bc les instructions sont exécutées "dès que possible". L'exécution se produit lorsqu'une nouvelle ligne est rencontrée et qu'il existe une ou plusieurs instructions complètes. En raison de cette exécution immédiate, les retours à la ligne sont très importants en bc. En fait, un point-virgule et une nouvelle ligne sont utilisés comme séparateurs d'instructions. Une nouvelle ligne mal placée entraînera une erreur de syntaxe. Comme les retours à la ligne sont des séparateurs d'instructions, il est possible de masquer un retour à la ligne en utilisant le caractère barre oblique inverse. La séquence "\", où est la nouvelle ligne apparaît à bc comme un espace au lieu d'une nouvelle ligne. Une liste d'instructions est une série d'instructions séparées par des points-virgules et des retours à la ligne. Voici une liste des instructions bc et ce qu'elles font : (les éléments entre crochets ([]) sont des parties facultatives de l'instruction.)

expression

Cette déclaration fait l'une des deux choses. Si l'expression commence par " ...", elle est considérée comme une instruction d'affectation. Si l'expression n'est pas une instruction d'affectation, l'expression est évaluée et imprimée dans la sortie. Une fois le numéro imprimé, une nouvelle ligne est imprimée. Par exemple, "a=1" est une instruction d'affectation et "(a=1)" est une expression qui a une affectation intégrée. Tous les nombres imprimés sont imprimés dans la base spécifiée par la variable obase. Les valeurs légales pour obase vont de 2 à BC_BASE_MAX. (Voir la section LIMITES.) Pour les bases 2 à 16, la méthode habituelle d'écriture des nombres est utilisée. Pour les bases supérieures à 16, bc utilise une méthode multi-chiffres pour imprimer les nombres où chaque chiffre de base supérieur est imprimé comme un nombre de base 10. Les chiffres à plusieurs caractères sont séparés par des espaces. Chaque chiffre contient le nombre de caractères requis pour représenter la valeur en base dix de "obase-1". Étant donné que les nombres sont d'une précision arbitraire, certains nombres peuvent ne pas être imprimables sur une seule ligne de sortie. Ces longs nombres seront répartis sur plusieurs lignes en utilisant le "\" comme dernier caractère sur une ligne. Le nombre maximum de caractères imprimés par ligne est de 70. En raison de la nature interactive de bc, l'impression d'un nombre a pour effet secondaire d'attribuer la valeur imprimée à la variable spéciale last . Cela permet à l'utilisateur de récupérer la dernière valeur imprimée sans avoir à retaper l'expression qui a imprimé le nombre. L'attribution à dernier est légale et remplacera la dernière valeur imprimée par la valeur attribuée. La nouvelle valeur attribuée restera jusqu'à ce que le numéro suivant soit imprimé ou qu'une autre valeur soit attribuée au dernier. (Certaines installations peuvent autoriser l'utilisation d'un seul point (.) qui ne fait pas partie d'un nombre comme notation abrégée pour last.)

string

La chaîne est imprimée sur la sortie. Les chaînes commencent par un guillemet double et contiennent tous les caractères jusqu'au guillemet double suivant. Tous les caractères sont pris littéralement, y compris toute nouvelle ligne. Aucun caractère de saut de ligne n'est imprimé après la chaîne.

print list

L'instruction print (une extension) fournit une autre méthode de sortie. La "liste" est une liste de chaînes et d'expressions séparées par des virgules. Chaque chaîne ou expression est imprimée dans l'ordre de la liste. Aucune nouvelle ligne de fin n'est imprimée. Les expressions sont évaluées et leur valeur est imprimée et affectée à la variable last. Les chaînes de l'instruction print sont imprimées dans la sortie et peuvent contenir des caractères spéciaux. Les caractères spéciaux commencent par le caractère barre oblique inverse (\). Les caractères spéciaux reconnus par bc sont "a" (alerte ou cloche), "b" (retour arrière), "f" (saut de page), "n" (nouvelle ligne), "r" (chariot retour), "q" (guillemets doubles), "t" (tabulation) et "\" (barre oblique inverse). Tout autre caractère suivant la barre oblique inverse sera ignoré.

{ statement_list }

C'est l'énoncé composé. Il permet de regrouper plusieurs instructions pour l'exécution.

if ( expression ) statement1 [else statement2]

L'instruction if évalue l'expression et exécute instruction1 ou instruction2 en fonction de la valeur de l'expression. Si l'expression est différente de zéro, instruction1 est exécutée. Si instruction2 est présente et que la valeur de l'expression est 0, alors instruction2 est exécutée. (La clause else est une extension.)

while ( expression ) statement

L'instruction while exécutera l'instruction tant que l'expression est différente de zéro. Il évalue l'expression avant chaque exécution de l'instruction. L'arrêt de la boucle est provoqué par une valeur d'expression nulle ou l'exécution d'une instruction break.

for ( [expression1] ; [expression2] ; [expression3] ) statement

L'instruction for contrôle l'exécution répétée de l'instruction. Expression1 est évaluée avant la boucle. Expression2 est évaluée avant chaque exécution de l'instruction. S'il est différent de zéro, l'instruction est évaluée. S'il est nul, la boucle est terminée. Après chaque exécution de l'instruction, expression3 est évaluée avant la réévaluation de expression2. Si expression1 ou expression3 sont manquantes, rien n'est évalué au point où ils le seraient. Si expression2 est manquante, cela revient à substituer la valeur 1 à expression2. (Les expressions facultatives sont une extension. POSIX bc nécessite les trois expressions.) Le code suivant est équivalent pour l'instruction for :

expression1;
while (expression2) {
   statement;
   expression3;
}
break

Cette instruction provoque une sortie forcée de l'instruction while ou for englobante la plus récente.

continue

L'instruction continue (une extension) fait que l'instruction for englobante la plus récente démarre l'itération suivante.

halt

L'instruction halt (une extension) est une instruction exécutée qui provoque l'arrêt du processeur bc uniquement lorsqu'il est exécuté. Par exemple, "if (0 == 1) halt" ne provoquera pas l'arrêt de bc car l'arrêt n'est pas exécuté.

return

Renvoie la valeur 0 d'une fonction. (Voir la section sur les fonctions.)

return ( expression )

Renvoie la valeur de l'expression d'une fonction. (Voir la section sur les fonctions.) En tant qu'extension, les parenthèses ne sont pas nécessaires.

DÉCLARATIONS PSEUDO

Ces déclarations ne sont pas des déclarations au sens traditionnel. Ce ne sont pas des instructions exécutées. Leur fonction est exécutée au moment de la "compilation".

limits

Affiche les limites locales appliquées par la version locale de bc. Il s'agit d'une extension.

quit

Lorsque l'instruction quit est lue, le processeur bc est arrêté, quel que soit l'endroit où se trouve l'instruction quit. Par exemple, "if (0 == 1) quit" entraînera l'arrêt de bc.

warranty

Imprimez un avis de garantie plus long. Il s'agit d'une extension.

LES FONCTIONS

Les fonctions fournissent une méthode de définition d'un calcul qui peut être exécuté ultérieurement. Les fonctions dans bc calculent toujours une valeur et la renvoient à l'appelant. Les définitions de fonction sont "dynamiques" dans le sens où une fonction est indéfinie jusqu'à ce qu'une définition soit rencontrée dans l'entrée. Cette définition est ensuite utilisée jusqu'à ce qu'une autre fonction de définition pour le même nom soit rencontrée. La nouvelle définition remplace alors l'ancienne définition. Une fonction est définie comme suit :

define name ( parameters ) { newline
    auto_list   statement_list }

Un appel de fonction est juste une expression de la forme "nom(paramètres)".

Les paramètres sont des nombres ou des tableaux (une extension). Dans la définition de la fonction, zéro ou plusieurs paramètres sont définis en listant leurs noms séparés par des virgules. Tous les paramètres sont des paramètres d'appel par valeur. Les tableaux sont spécifiés dans la définition des paramètres par la notation "nom[]". Dans l'appel de fonction, les paramètres réels sont des expressions complètes pour les paramètres numériques. La même notation est utilisée pour passer des tableaux que pour définir des paramètres de tableau. Le tableau nommé est passé par valeur à la fonction. Comme les définitions de fonction sont dynamiques, les numéros et types de paramètres sont vérifiés lorsqu'une fonction est appelée. Toute incompatibilité dans le nombre ou les types de paramètres entraînera une erreur d'exécution. Une erreur d'exécution se produira également pour l'appel à une fonction indéfinie.

La auto_list est une liste facultative de variables à usage "local". La syntaxe de la liste automatique (si présente) est "auto nom, ... ;". (Le point-virgule est facultatif.) Chaque nom est le nom d'une variable automatique. Les tableaux peuvent être spécifiés en utilisant la même notation que celle utilisée dans les paramètres. Ces variables ont leurs valeurs poussées sur une pile au début de la fonction. Les variables sont alors initialisées à zéro et utilisées tout au long de l'exécution de la fonction. A la sortie de la fonction, ces variables sont dépilées afin que la valeur d'origine (au moment de l'appel de la fonction) de ces variables soit restaurée. Les paramètres sont en réalité des variables automatiques qui sont initialisées à une valeur fournie dans l'appel de fonction. Les variables automatiques sont différentes des variables locales traditionnelles car si la fonction A appelle la fonction B, B peut accéder aux variables automatiques de la fonction A en utilisant simplement le même nom, à moins que la fonction B ne les ait appelées variables automatiques. Étant donné que les variables et les paramètres automatiques sont poussés sur une pile, bc prend en charge les fonctions récursives.

Le corps de la fonction est une liste d'instructions bc. Encore une fois, les instructions sont séparées par des points-virgules ou des retours à la ligne. Les instructions de retour provoquent l'arrêt d'une fonction et le retour d'une valeur. Il existe deux versions de l'instruction return. La première forme, "return", renvoie la valeur 0 à l'expression appelante. La deuxième forme, "return ( expression )", calcule la valeur de l'expression et renvoie cette valeur à l'expression appelante. Il y a un "return (0)" implicite à la fin de chaque fonction. Cela permet à une fonction de se terminer et de renvoyer 0 sans instruction de retour explicite.

Les fonctions modifient également l'utilisation de la variable ibase. Toutes les constantes du corps de la fonction seront converties en utilisant la valeur de ibase au moment de l'appel de la fonction. Les modifications de ibase seront ignorées lors de l'exécution de la fonction, sauf pour la fonction standard read, qui utilisera toujours la valeur actuelle de ibase pour conversion de nombres.

Plusieurs extensions ont été ajoutées aux fonctions. Premièrement, le format de la définition a été légèrement assoupli. La norme exige que l'accolade ouvrante soit sur la même ligne que le mot-clé define et toutes les autres parties doivent être sur les lignes suivantes. Cette version de bc autorisera n'importe quel nombre de retours à la ligne avant et après l'accolade ouvrante de la fonction. Par exemple, les définitions suivantes sont légales.

define d (n) { return (2*n); }
define d (n)
  { return (2*n); }

Les fonctions peuvent être définies comme void. Une fonction void ne renvoie aucune valeur et ne peut donc être utilisée à aucun endroit nécessitant une valeur. Une fonction void ne produit aucune sortie lorsqu'elle est appelée par elle-même sur une ligne d'entrée. Le mot clé void est placé entre le mot clé define et le nom de la fonction. Par exemple, considérez la session suivante.

define py (y) { print "--->", y, "<---", "\n"; }
define void px (x) { print "--->", x, "<---", "\n"; }
py(1)
--->1<---
0
px(1)
--->1<---

Puisque py n'est pas une fonction vide, l'appel de py(1) imprime la sortie souhaitée, puis imprime une deuxième ligne qui est la valeur de la fonction. Étant donné que la valeur d'une fonction qui ne reçoit pas d'instruction de retour explicite est zéro, le zéro est imprimé. Pour px(1), aucun zéro n'est imprimé car la fonction est une fonction vide.

Aussi, appel par variable pour les tableaux a été ajouté. Pour déclarer un appel par tableau de variable, la déclaration du paramètre tableau dans la définition de la fonction ressemble à "*nom[]". L'appel à la fonction reste le même que l'appel par des tableaux de valeurs.

BIBLIOTHÈQUE DE MATHÉMATIQUES

Si bc est appelé avec l'option -l, une bibliothèque mathématique est préchargée et l'échelle par défaut est définie sur 20. Les fonctions mathématiques calculeront leurs résultats selon l'échelle définie à l'heure de leur appel. La bibliothèque mathématique définit les fonctions suivantes :

s (x)

Le sinus de x, x est en radians.

c (x)

Le cosinus de x, x est en radians.

a (x)

L'arctangente de x, arctangente renvoie des radians.

l (x)

Le logarithme naturel de x.

e (x)

La fonction exponentielle d'élévation de e à la valeur x.

j (n,x)

La fonction de Bessel d'ordre entier n de x.

EXEMPLES

Dans /bin/sh, ce qui suit attribuera la valeur de "pi" à la variable shell pi.

pi=$(echo "scale=10; 4*a(1)" | bc -l)

Voici la définition de la fonction exponentielle utilisée dans la bibliothèque mathématique. Cette fonction est écrite en POSIX bc.

scale = 20

/* Uses the fact that e^x = (e^(x/2))^2
   When x is small enough, we use the series:
     e^x = 1 + x + x^2/2! + x^3/3! + ...
*/

define e(x) {
  auto  a, d, e, f, i, m, v, z

  /* Check the sign of x. */
  if (x<0) {
    m = 1
    x = -x
  } 

  /* Precondition x. */
  z = scale;
  scale = 4 + z + .44*x;
  while (x > 1) {
    f += 1;
    x /= 2;
  }

  /* Initialize the variables. */
  v = 1+x
  a = x
  d = 1

  for (i=2; 1; i++) {
    e = (a *= x) / (d *= i)
    if (e == 0) {
      if (f>0) while (f--)  v = v*v;
      scale = z
      if (m) return (1/v);
      return (v/1);
    }
    v += e
  }
}

Le code suivant utilise les fonctionnalités étendues de bc pour implémenter un programme simple permettant de calculer les soldes des chéquiers. Ce programme est mieux conservé dans un fichier afin qu'il puisse être utilisé plusieurs fois sans avoir à le retaper à chaque utilisation.

scale=2
print "\nCheck book program!\n"
print "  Remember, deposits are negative transactions.\n"
print "  Exit by a 0 transaction.\n\n"

print "Initial balance? "; bal = read()
bal /= 1
print "\n"
while (1) {
  "current balance = "; bal
  "transaction? "; trans = read()
  if (trans == 0) break;
  bal -= trans
  bal /= 1
}
quit

Voici la définition de la fonction factorielle récursive.

define f (x) {
  if (x <= 1) return (1);
  return (f(x-1) * x);
}

OPTIONS READLINE ET LIBEDIT

GNU bc peut être compilé (via une option de configuration) pour utiliser la bibliothèque d'éditeur d'entrée GNU readline ou la bibliothèque BSD libedit. Cela permet à l'utilisateur de modifier les lignes avant de les envoyer à bc. Il permet également un historique des lignes précédentes tapées. Lorsque cette option est sélectionnée, bc a une autre variable spéciale. Cette variable spéciale, historique est le nombre de lignes d'historique conservées. Pour readline, une valeur de -1 signifie qu'un nombre illimité de lignes d'historique sont conservées. Définir la valeur de history sur un nombre positif limite le nombre de lignes d'historique au nombre donné. La valeur 0 désactive la fonction d'historique. La valeur par défaut est 100. Pour plus d'informations, lisez les manuels d'utilisation des bibliothèques GNU readline, history et BSD libedit. On ne peut pas activer à la fois readline et libedit en même temps.

DIFFÉRENCES

Cette version de bc a été implémentée à partir du brouillon POSIX P1003.2/D11 et contient plusieurs différences et extensions par rapport au brouillon et aux implémentations traditionnelles. Il n'est pas implémenté de manière traditionnelle en utilisant dc(1). Cette version est un processus unique qui analyse et exécute une traduction en code binaire du programme. Il existe une option "non documentée" (-c) qui oblige le programme à sortir le code d'octet sur la sortie standard au lieu de l'exécuter. Il était principalement utilisé pour déboguer l'analyseur et préparer la bibliothèque mathématique.

Une source majeure de différences est les extensions, où une fonctionnalité est étendue pour ajouter plus de fonctionnalités et d'ajouts, où de nouvelles fonctionnalités sont ajoutées. Voici la liste des différences et des extensions.

LANG environment

Cette version n'est pas conforme au standard POSIX dans le traitement de la variable d'environnement LANG et de toutes les variables d'environnement commençant par LC_.

names

Traditionnel et POSIX bc ont des noms à une seule lettre pour les fonctions, les variables et les tableaux. Ils ont été étendus pour devenir des noms à plusieurs caractères qui commencent par une lettre et peuvent contenir des lettres, des chiffres et le caractère de soulignement.

Strings

Les chaînes ne peuvent pas contenir de caractères NUL. POSIX dit que tous les caractères doivent être inclus dans des chaînes.

last

POSIX bc n'a pas de variable last. Certaines implémentations de bc utilisent le point (.) de la même manière.

comparisons

POSIX bc autorise les comparaisons uniquement dans l'instruction if, l'instruction while et la deuxième expression de l'instruction for. De plus, une seule opération relationnelle est autorisée dans chacune de ces instructions.

if statement, else clause

POSIX bc n'a pas de clause else.

for statement

POSIX bc exige que toutes les expressions soient présentes dans l'instruction for.

&&, ||, !

POSIX bc n'a pas les opérateurs logiques.

read function

POSIX bc n'a pas de fonction de lecture.

print statement

POSIX bc n'a pas d'instruction print .

continue statement

POSIX bc n'a pas d'instruction continue.

return statement

POSIX bc nécessite des parenthèses autour de l'expression de retour.

array parameters

POSIX bc ne prend pas (actuellement) en charge les paramètres de tableau dans leur intégralité. La grammaire POSIX autorise les tableaux dans les définitions de fonctions, mais ne fournit pas de méthode pour spécifier un tableau en tant que paramètre réel. (Il s'agit très probablement d'un oubli dans la grammaire.) Les implémentations traditionnelles de bc n'ont que des paramètres de tableau d'appel par valeur.

function format

POSIX bc nécessite l'accolade ouvrante sur la même ligne que le mot clé define et l'instruction auto sur la ligne suivante.

=+, =-, =*, =/, =%, =^

POSIX bc ne nécessite pas la définition de ces opérateurs d'affectation "à l'ancienne". Cette version peut autoriser ces affectations "à l'ancienne". Utilisez la déclaration de limites pour voir si la version installée les prend en charge. S'il prend en charge les opérateurs d'affectation "ancien style", l'instruction "a =- 1" décrémentera a de 1 au lieu de définir a à la valeur -1.

spaces in numbers

D'autres implémentations de bc autorisent les espaces dans les nombres. Par exemple, "x=1 3" attribuerait la valeur 13 à la variable x. La même instruction provoquerait une erreur de syntaxe dans cette version de bc.

errors and execution

Cette implémentation diffère des autres implémentations en termes de code qui sera exécuté lorsque la syntaxe et d'autres erreurs sont trouvées dans le programme. Si une erreur de syntaxe est détectée dans une définition de fonction, la récupération sur erreur essaie de trouver le début d'une instruction et continue d'analyser la fonction. Une fois qu'une erreur de syntaxe est trouvée dans la fonction, la fonction ne sera pas appelable et deviendra indéfinie. Les erreurs de syntaxe dans le code d'exécution interactif invalideront le bloc d'exécution en cours. Le bloc d'exécution se termine par une fin de ligne qui apparaît après une séquence complète d'instructions. Par exemple,

a = 1
b = 2

a deux blocs d'exécution et

{ a = 1
  b = 2 }

a un bloc d'exécution. Toute erreur d'exécution mettra fin à l'exécution du bloc d'exécution en cours. Un avertissement d'exécution ne mettra pas fin au bloc d'exécution en cours.

Interrupts

Lors d'une session interactive, le signal SIGINT (généralement généré par le caractère control-C du terminal) provoquera l'interruption de l'exécution du bloc d'exécution en cours. Il affichera une erreur "d'exécution" indiquant quelle fonction a été interrompue. Une fois que toutes les structures d'exécution ont été nettoyées, un message sera imprimé pour informer l'utilisateur que bc est prêt pour plus d'entrées. Toutes les fonctions précédemment définies restent définies et la valeur de toutes les variables non automatiques est la valeur au point d'interruption. Toutes les variables automatiques et les paramètres de fonction sont supprimés pendant le processus de nettoyage. Au cours d'une session non interactive, le signal SIGINT mettra fin à toute l'exécution de bc.

LIMITES

Voici les limites actuellement en place pour ce processeur bc. Certains d'entre eux peuvent avoir été modifiés par une installation. Utilisez l'énoncé des limites pour voir les valeurs réelles.

BC_BASE_MAX

La base de sortie maximale est actuellement fixée à 999. La base d'entrée maximale est de 16.

BC_DIM_MAX

Il s'agit actuellement d'une limite arbitraire de 65535 telle que distribuée. Votre installation peut être différente.

BC_SCALE_MAX

Le nombre de chiffres après la virgule est limité à INT_MAX chiffres. De plus, le nombre de chiffres avant la virgule décimale est limité à INT_MAX chiffres.

BC_STRING_MAX

La limite du nombre de caractères dans une chaîne est de INT_MAX caractères.

exponent

La valeur de l'exposant dans l'opération d'élévation (^) est limitée à LONG_MAX.

variable names

La limite actuelle du nombre de noms uniques est de 32 767 pour chacune des variables simples, des tableaux et des fonctions.

VARIABLES D'ENVIRONNEMENT

Les variables d'environnement suivantes sont traitées par bc :

POSIXLY_CORRECT

C'est la même chose que l'option -s.

BC_ENV_ARGS

C'est un autre mécanisme pour obtenir des arguments pour bc. Le format est le même que celui des arguments de la ligne de commande. Ces arguments sont traités en premier, de sorte que tous les fichiers répertoriés dans les arguments d'environnement sont traités avant tous les fichiers d'arguments de ligne de commande. Cela permet à l'utilisateur de configurer des options "standard" et des fichiers à traiter à chaque invocation de bc. Les fichiers dans les variables d'environnement contiennent généralement des définitions de fonctions pour les fonctions que l'utilisateur souhaite définir à chaque fois que bc est exécuté.

BC_LINE_LENGTH

Il doit s'agir d'un nombre entier spécifiant le nombre de caractères dans une ligne de sortie pour les nombres. Cela inclut les barres obliques inverses et les sauts de ligne pour les nombres longs. Par extension, la valeur zéro désactive la fonction multiligne. Toute autre valeur de cette variable inférieure à 3 définit la longueur de la ligne sur 70.

DIAGNOSTIQUE

Si un fichier sur la ligne de commande ne peut pas être ouvert, bc signalera que le fichier est indisponible et se terminera. En outre, il existe des diagnostics de compilation et d'exécution qui devraient être explicites.

INSECTES

La récupération d'erreur n'est pas encore très bonne.

Envoyez les rapports de bogues par e-mail à bug-bc@gnu.org. Assurez-vous d'inclure le mot ``bc'' quelque part dans le champ ``Subject:''.

AUTEUR

Philip A. Nelson
philnelson@acm.org

REMERCIEMENTS

L'auteur tient à remercier Steve Sommars (Steve.Sommars@att.com) pour son aide précieuse dans le test de l'implémentation. Beaucoup de bonnes suggestions ont été données. C'est un bien meilleur produit grâce à son implication.