Provided by:
manpages-es-extra_0.8a-17_all 
NOMBRE
bc - Un lenguaje de calculo de precision arbitraria
SINTAXIS
bc [ -lwsqv ] [opciones largas] [ fichero ... ]
VERSI'ON
Esta pagina de manual documenta la version 1.04 de GNU bc.
DESCRIPCI'ON
bc es un lenguaje que permite la ejecucion interactiva de sentencias
con precision numerica arbitraria. La sintaxis es similar a la del
lenguaje de programacion C. Se puede disponer de una biblioteca
matematica estandar a traves de una opcion en la linea de comando. En
ese caso, la biblioteca matematica se determina antes de procesar
ningun fichero. bc comienza procesando en orden todos los ficheros
dados en la linea de comando. Despues de que todos los ficheros hayan
sido procesados, bc lee la entrada estandar. Todo el codigo es
ejecutado tal y como es leido. (Si un fichero contiene un comando que
detiene el procesador bc nunca leera la entrada estandar.)
Esta version de bc tiene varias ampliaciones adicionales a las
tradicionales implementaciones de bc y el estandar POSIX. Las opciones
en la linea de comando pueden causar que estas extensiones impriman un
aviso o sean rechazadas. Este documento describe el lenguaje aceptado
por este procesador. Las ampliaciones seran identificadas como tales.
OPCIONES
-l Selecciona la biblioteca matematica estandar.
-w Da mensajes de advertencia ante las ampliaciones al bc de POSIX.
-s Procesa exactamente como el lenguaje bc de POSIX.
-q No imprime el habitual mensaje de bienvenida del GNU bc.
-v Imprime el numero de version el copyright y sale.
--mathlib
Selecciona la biblioteca matematica estandar.
--warn Da mensajes de advertencia ante las ampliaciones al bc de POSIX.
--standard
Procesa exactamente como el lenguaje bc de POSIX.
--quiet
No imprime el habitual mensaje de bienvenida del GNU bc.
--version
Imprime el numero de version el copyright y sale.
N'UMEROS
El elemento mas basico en bc es el numero. Los numeros son de precision
arbitraria, tanto en la parte entera como en la fraccionaria. Todos
los numeros son representados internamente en decimal y toda la
computacion es hecha en decimal. (Esta version trunca los resultados de
las operaciones division y multiplicacion). Los numeros tienen dos
atributos, la longitud y la escala. La longitud es el numero total de
digitos decimales significativas y la escala el numero de digitos
decimales tras la coma decimal. Por ejemplo:
.000001 tiene longitud 6 y escala 6.
1935.000 tiene longitud 7 y escala 3.
VARIABLES
Los numeros son almacenados en dos tipos de variables, variables
simples y matrices. Ambos tipos son designados por nombres. Estos
nombres comienzan con una letra, seguida por cualquier numero de
letras, digitos y caracteres de subrayado. Todas las letras deben ir en
minusculas. (Estos nombres alfanumericos son una ampliacion. En el bc
de POSIX todos los nombres son una sola letra minuscula). El tipo de
variable queda claro segun el contexto ya que a todas las variables de
tipo matriz les sigue unos corchetes ([]).
Hay cuatro variables especiales, scale, ibase, obase y last. scale
define como son tratadas los digitos tras la coma decimal en algunas
operaciones. El valor por defecto de scale es 0. ibase y obase definen
la base numerica de conversion para la entrada y la salida. El valor
por defecto para ambos es la base 10. last (una ampliacion) es la
variable en la que se guardar el ultimo numero mostrado. Todo esto sera
tratado en detalle cuando proceda. Todas estas variables pueden tener
un valor asignado asi como ser usadas en expresiones.
COMENTARIOS
Los comentarios en bc comienzan con los caracteres /* y finalizan con
los caracteres */. Los comentarios pueden empezar en cualquier lugar y
aparecen como un solo espacio en la entrada. (Esto hace que delimiten
otros elementos de entrada. Por ejemplo, un comentario no puede
encontrarse en medio del nombre de una variable). Los comentarios
pueden incluir saltos de linea.
Para poder usar macros (scripts) en bc, la posibilidad de incluir
comentarios de una sola linea ha sido anadida como ampliacion. Estos
comienzan con el caracter # y continuan hasta el final de la linea. El
final de linea no es parte del comentario y es procesado de forma
normal.
EXPRESIONES
Los numeros son manipulados por las expresiones y las sentencias. Como
el lenguaje fue disenado para ser interactivo, las sentencias y
expresiones son ejecutadas tan pronto como es posible. No hay programa
principal ("main"). En su lugar, el codigo es ejecutado tal y como se
encuentra. (Las funciones, tratadas en detalle mas abajo, se definen
cuando se encuentran).
Una constante es la expresion mas simple. bc convierte internamente las
constantes en numeros decimales usando la base de entrada activa,
especificada por la variable ibase. (Hay una excepcion en las
funciones). Los valores permitidos para ibase van del 2 hasta el 16. Si
se asigna un valor a ibase fuera de este rango se cambiara por 2 o 16.
Los numeros en la entrada pueden formarse con los caracteres 0-9 y A-F.
(Nota: Deben ir en mayusculas. Las minusculas son nombres de
variables). Los numeros de un solo digito tienen siempre el valor del
digito, sea cual sea el valor de ibase. (ej. A = 10.). En los numeros
de mas de un digito bc cambia todos los digitos mayores o iguales a
ibase al valor de ibase-1. Esto hace que el numero FFF sea siempre el
mayor numero de 3 digitos de la base de entrada.
Las expresiones mas complejas son similares a muchos otros lenguajes de
alto nivel. Como solo hay un tipo de numero, no hay reglas para mezclar
tipos. En cambio, hay reglas para la escala de las expresiones. Cada
expresion tiene una escala. Esta es derivada de la escala de los
numeros originales, la operacion realizada y, en muchos casos, el valor
de la variable scale. Los valores permitidos para scale son desde 0
hasta el maximo numero representable por un entero en C.
En las siguientes descripciones de expresiones permitidas, "expr" se
usa para indicar un expresion completa y "var" una variable, simple o
matricial. Una variable simple es, simplemente
nombre
y una matriz se designa asi
nombre[expr]
Si no se especifica la escala del resultado, esta sera la maxima escala
de las expresiones implicadas.
- expr El resultado es la expresion negada.
++ var La variable es incrementada en uno y el nuevo valor es el
resultado de la expresion.
-- var La variable es decrementada en uno y el nuevo valor es el
resultado de la expresion.
var ++ El resultado de la expresion es el valor de la variable y
entonces la variable es incrementada en uno.
var -- El resultado de la expresion es el valor de la variable y
entonces la variable es decrementada en uno.
expr + expr
El resultado de la expresion es la suma de las dos expresiones.
expr - expr
El resultado de la expresion es la diferencia de las dos
expresiones.
expr * expr
El resultado de la expresion es el producto de las dos
expresiones.
expr / expr
El resultado de la expresion es el cociente de las dos
expresiones. La escala del resultado es el valor de la variable
scale.
expr % expr
El resultado de la expresion es el "resto" y se calcula de la
siguiente manera. Para calcular a%b, primero se calcula a/b en
scale digitos. Este resultado es usado para calcular a-(a/b)*b
a la escala que resulte mayor, scale+scale(b) o scale(a). Si
scale vale cero y ambas expresiones son enteros esta expresion
calcula el resto entero.
expr ^ expr
El resultado de la expresion es el valor de la primera elevada a
la segunda. La segunda expresion debe ser un entero. (Si la
segunda expresion no es un entero, se genera un mensaje de
advertencia y la expresion es truncada a un valor entero). La
escala del resultado es scale si el exponente es negativo. Si el
exponente es positivo la escala del resultado es el minimo de
estos valores: la escala de la base por el exponente o el maximo
de scale y la escala de la base. (ej. scale(a^b) =
min(scale(a)*b, max( scale, scale(a))).). Hay que tener en
cuenta que el resultado de expr^0 siempre sera 1.
( expr )
Altera la precedencia estandar para forzar la evaluacion de la
expresion.
var = expr
Se asigna a la variable el valor de la expresion.
var <op>= expr
Es equivalente a "var = var <op> expr" con la excepcion de que
"var" solo es evaluada una vez. Esto puede afectar si "var" es
una matriz.
Las expresiones relacionales son de un tipo especial que siempre se
evaluan a 0 o 1, 0 si la relacion es falsa y 1 si la relacion es
verdadera. Pueden aparecer en cualquier expresion permitida. (El bc de
POSIX solo permite el uso de expresiones relacionales en las sentencias
if, while y for y solo una expresion relacional en cada una de ellas).
Los operadores relacionales son:
expr1 < expr2
El resultado es 1 si expr1 es estrictamente menor que expr2.
expr1 <= expr2
El resultado es 1 si expr1 es menor o igual que expr2.
expr1 > expr2
El resultado es 1 si expr1 es estrictamente mayor que expr2.
expr1 >= expr2
El resultado es 1 si expr1 es mayor o igual que expr2.
expr1 == expr2
El resultado es 1 si expr1 es igual a expr2.
expr1 != expr2
El resultado es 1 si expr1 no es igual a expr2.
Las operaciones booleanas tambien estan permitidas. (El bc de POSIX NO
tiene operaciones booleanas). El resultado de toda operacion booleana
es 0 o 1 (falso o verdadero) como en las expresiones relacionales. Los
operadores booleanos son:
!expr El resultado es 1 si expr es 0.
expr && expr
El resultado es 1 si ambas expresiones son distintas de 0.
expr || expr
El resultado es 1 si alguna de las expresiones es distinta de 0.
La precedencia de las expresiones es la siguiente (de menor a mayor):
operador || , asociativo por la izquierda
operador && , asociativo por la izquierda
operador ! , no asociativo
operadores relacionales, asociativos por la izquierda
operador asignacion, asociativo por la derecha
operadores + y - , asociativos por la izquierda
operadores *, / y % , asociativos por la izquierda
operador ^ , asociativo por la derecha
operador unario - , no asociativo
operadores ++ y -- , no asociativo
Esta precedencia fue elegida para que los programas acordes con el bc
de POSIX funcionaran correctamente. Esto hara que el uso de operadores
relacionales y logicos tenga un comportamiento inusual cuando se usen
con expresiones de asignacion. Considere la expresion:
a = 3 < 5
La mayoria de los programadores de C asumirian que se asignaria el
resultado de "3 < 5" (el valor 1) a la variable "a". Lo que ocurre en
bc es que se asigna el valor 3 a la variable "a" y entonces se compara
3 con 5. Es mejor usar parentesis cuando se usan operadores
relacionales y logicos con operadores de asignacion.
Hay algunas expresiones especiales mas en bc. Estas estan relacionadas
con las funciones definidas por el usuario y las funciones estandar.
Tienen la forma "nombre(par'ametros)". Las funciones definidas por el
usuario son tratadas en la seccion FUNCIONES. Las funciones estandar
son:
length ( expresion )
EL valor de la funcion length es el numero de digitos
significativos en la expresion.
read ( )
La funcion read (una ampliacion) leera un numero de la entrada
estandar, independientemente del lugar donde aparezca la
funcion. Tenga cuidado pues esto puede causar problemas
mezclando datos y programa en la entrada estandar. El mejor uso
de esta funcion es ponerla en un programa previamente escrito
que necesite la entrada del usuario, pero nunca permitiendo que
el usuario introduzca codigo de programa. El valor de la funcion
read es el numero leido de la entrada estandar usando el valor
de la variable ibase para la base de conversion.
scale ( expresion )
El valor de la funcion scale es el numero de digitos tras la
coma decimal en la expresion.
sqrt ( expresion )
El valor de la funcion sqrt es la raiz cuadrada de la expresion.
Si la expresion es negativa, se genera un error en tiempo de
ejecucion.
SENTENCIAS
Las sentencias (como en la mayoria de los lenguajes algebraicos)
proporcionan la secuencia de las evaluacion de las expresiones. En bc
las sentencias son ejecutadas "tan pronto como es posible". La
ejecucion ocurre cuando se encuentra un cambio de linea y hay una o mas
sentencias completas. Debido a esta ejecucion inmediata, los cambios de
linea son muy importantes en bc. En realidad, tanto el punto y coma
como el cambio de linea son usados como separadores de sentencias. Un
cambio de linea en un lugar inapropiado provocara un error de sintaxis.
Es posible ocultar el que un cambio de linea sea un separador de
sentencias usando el caracter de contra-barra. bc toma la secuencia
"\<nl>", donde <nl> es el cambio de linea, como un espacio en blanco en
lugar de como un cambio de linea. Una lista de sentencias es una serie
de sentencias separadas por punto y coma y cambios de linea. Lo
siguiente es un lista de sentencias y la descripcion de lo que
realizan: (Las partes entre corchetes de las sentencias son
opcionales).
expresion
Esta sentencia hace una de estas dos cosas. Si la expresion
comienza con "<variable> <asignacion> ...", es considerada como
una sentencia de asignacion. Si no es una sentencia de
asignacion, la expresion es evaluada e impresa en la salida.
Tras el numero viene un cambio de linea. Por ejemplo, "a=1" es
una sentencia de asignacion y "(a=1)" es una expresion que tiene
una asignacion incluida. Todos los numeros se imprimen en la
base especificada por la variable obase. Los valores posibles
para obase van desde 2 hasta BC_BASE_MAX. (Ver seccion LIMITES).
Para las bases comprendidas entre 2 y 16, se usa el metodo usual
de impresion. Para las bases mayores de 16, bc usa un metodo de
impresion en el que utiliza digitos multi-caracter para imprimir
cada digito mayor que la base como un numero en base 10. Los
digitos multi-caracter son separados por espacios. Cada digito
emplea tantos caracteres como sean necesarios para representar
"obase-1" en base diez. Como los numeros son de precision
arbitraria, puede que algunos numeros no se puedan imprimir en
una sola linea. Estos numeros grandes seran repartidos en varias
lineas con el caracter "\" al final de cada linea. El numero
maximo de caracteres que se imprimen por linea es 70. Debido a
la naturaleza interactiva de bc, la impresion de un numero lleva
consigo la asignacion del valor impreso a la variable especial
last. Esto permite al usuario utilizar el ultimo valor impreso
sin tener que volver a teclear la expresion que causo su
impresion. Esta permitido asignar valores a last y esto
sobreescribira el ultimo valor impreso con el valor asignado. El
nuevo valor permanecera hasta que se imprima el siguiente numero
o se le asigne otro valor a last. (Algunas instalaciones pueden
permitir usar un punto (.) que no sea parte de un numero como
una notacion mas corta para last).
cadena Se imprime la cadena en la salida. Las cadenas comienzan con una
comilla doble y contienen todos los caracteres hasta la
siguiente comilla doble. Todos los caracteres son tomados
literalmente, incluidos los cambios de linea. Tras la cadena no
se cambia de linea.
print lista
La sentencia print (una ampliacion) proporciona otro metodo de
impresion. La "lista" es una lista de cadenas y expresiones
separadas por comas. La lista se imprime en el orden en el que
esta. Tras la lista no se cambia de linea. Las expresiones son
evaluadas y sus valores impresos y asignados a la variable last.
Las cadenas se imprimen en la salida y pueden contener
caracteres especiales. Los caracteres especiales comienzan con
el caracter de contra-barra (\). bc reconoce los caracteres
especiales "a" (alerta o campana), "b" (borrar caracter
(backspace)), "f" (salto de linea), "n" (nueva linea), "r"
(retorno de carro), "q" (comilla doble), "t" (tabulador), y "\"
(contra-barra). Cualquier otro caracter que siga a una contra-
barra sera ignorado.
{ lista_de_sentencias }
Esta es la sentencia compuesta. Permite ejecutar varias
sentencias agrupadas.
if ( expresion ) sentencia1 [else sentencia2]
Esta sentencia evalua la expresion y ejecuta la sentencia1 o la
sentencia2 dependiendo del valor de la expresion. Si el valor es
distinto de 0, se ejecuta la sentencia1. Si se da la sentencia2
y el valor de la expresion es 0, entonces se ejecuta la
sentencia2. (La clausula else es una ampliacion).
while ( expresion ) sentencia
Se ejecuta la sentencia mientras la expresion sea distinta de 0.
Se evalua la expresion antes de cada ejecucion de la sentencia.
El bucle termina al tomar la expresion el valor 0 o ante una
sentencia break.
for ( [expresion1] ; [expresion2] ; [expresion3] ) sentencia
La sentencia for controla la ejecucion repetitiva de la
sentencia. La expresion1 es evaluada antes del bucle. La
expresion2 es evaluada antes de cada ejecucion de la sentencia.
Si es 0, el bucle termina. Despues de cada ejecucion de la
sentencia, se evalua la expresion3 antes de reevaluar la
expresion2. Si la expresion1 o la expresion3 no se dan, no se
evalua nada en su lugar. Si la expresion2 no se da, es lo mismo
que sustituirla por el valor 1. (El que las expresiones sean
opcionales es una ampliacion. El bc de POSIX requiere las tres
expresiones). Este es el codigo equivalente para la sentencia
for:
expresion1;
while (expresion2) {
sentencia;
expresion3;
}
break Esta sentencia fuerza la salida de la sentencia while o for mas
reciente.
continue
La sentencia continue (una ampliacion) provoca que la sentencia
for mas reciente comience una nueva iteracion.
halt La sentencia halt (una ampliacion) provoca que el procesador bc
termine solo cuando es ejecutada. Por ejemplo, "if (0 == 1)
halt" no hara que bc termine porque no llega a ejecutarse la
sentencia halt.
return Devuelve el valor 0 desde una funcion. (Ver seccion sobre
funciones).
return ( expresion )
Devuelve el valor de la expresion desde una funcion. (Ver
seccion sobre funciones).
PSEUDO SENTENCIAS
Estas sentencias no son sentencias en el sentido tradicional. No son
sentencias que se ejecuten. Su funcion se realiza en "tiempo de
compilacion".
limits Imprime los limites locales forzados por la version local de bc.
Esto es una ampliacion.
quit Cuando la sentencia quit se lee, el procesador bc termina,
cualquiera que sea el lugar donde se encuentre la sentencia
quit. Por ejemplo, "if (0 == 1) quit" hara que bc termine.
warranty
Imprime un aviso largo sobre la garantia. Esto es una
ampliacion.
FUNCIONES
Las funciones proporcionan un metodo para definir un calculo que sera
ejecutado mas tarde. Las funciones en bc siempre calculan un valor que
devuelven a quien la ha llamado. La definicion de las funciones son
"dinamicas" en el sentido de que una funcion esta indefinida hasta que
se encuentra una definicion en la entrada. Se usa esa definicion hasta
que se encuentra otra definicion de funcion con el mismo nombre. La
nueva definicion reemplaza a la anterior. Una funcion se define como
sigue:
define nombre ( par'ametros ) { nueva_l'inea
auto_lista lista_de_sentencias }
La ejecucion de una funcion es simplemente una expresion de la forma
"nombre(par'ametros)".
Los parametros son numeros o matrices (una ampliacion). En la
definicion de la funcion, se definen cero o mas parametros listando sus
nombres separados por comas. Los numeros son llamados por valor. Las
matrices son llamadas por variable. Las matrices se especifican en la
definicion de parametros mediante la notacion "name[]". En la llamada a
la funcion, los parametros son expresiones completas para los
parametros que son numeros. Se usa la misma notacion para pasar
matrices que para definirlas en los parametros. El nombre de la matriz
se pasa a la funcion por variable. Como las definiciones de las
funciones son dinamicas, el numero de parametros y los tipos se
comprueban en el momento de llamar a la funcion. Cualquier discrepancia
en el numero o en el tipo de los parametros provocara un error en
tiempo de ejecucion. Tambien se provocara un error al llamar a una
funcion no definida.
La auto_lista es una lista opcional de variables para uso "local". La
sintaxis de esta lista (si se da) es "auto nombre, ... ;". (El punto y
coma es opcional). Cada nombre es el nombre de una variable auto. Las
matrices se pueden especificar con la misma notacion que se usa en los
parametros. Los valores de estas variables se guardan en una pila al
comienzo de la funcion. Entonces son inicializadas a cero y se usan en
el transcurso de la funcion. Al finalizar la funcion, se recuperan de
la pila los valores originales (en el momento de la llamada a la
funcion). Los parametros son realmente variables auto que se
inicializan al valor proporcionado en la llamada a la funcion. Las
variables auto son diferentes de las tradicionales variables locales en
que si la funcion A llama a la funcion B, B puede acceder a las
variables auto de A simplemente usando sus nombres, a no ser que la
funcion B tenga variables auto del mismo nombre. Como tanto las
variables auto como los parametros son guardados en una pila, bc admite
funciones recursivas.
El cuerpo de la funcion es una lista de sentencias de bc. De nuevo las
sentencias van separadas por punto y coma o cambio de linea. La
sentencia return hace que la funcion termine y devuelva un valor a la
expresion que ha llamado a la funcion.. La primera forma, "return",
devuelve el valor 0. La segunda forma "return ( expresi'on )", calcula
el valor de la expresion y lo devuelve a la expresion que ha llamado la
funcion. Hay un "return (0)" implicito al final de cada funcion. Esto
permite a una funcion terminar y devolver 0, sin necesidad de una
sentencia return explicita.
Las funciones tambien cambian el uso de la variable ibase. Todas las
constantes en el cuerpo de la funcion son convertidas usando el valor
de ibase en el momento de llamar a la funcion. Los cambios de ibase
seran ignorados durante la ejecucion de la funcion excepto para la
funcion estandar read, que siempre usara el valor actual de ibase para
la conversion de los numeros.
BIBLIOTECA MATEM'ATICA
Si se invoca bc con la opcion -l, una biblioteca matematica es pre-
cargada y la escala por defecto se pone a 20. Las funciones matematicas
calcularan sus resultados a la escala definida en el momento de su
llamada. La biblioteca matematica define las siguientes funciones:
s (x) El seno de x, con x en radianes.
c (x) El coseno de x, con x en radianes.
a (x) El arcotangente de x, con el resultado en radianes.
l (x) El logaritmo natural de x.
e (x) La funcion exponencial resultante de elevar e al valor de x.
j (n,x)
La funcion bessel de orden entero n de x.
EJEMPLOS
En /bin/sh, lo siguiente asignara el valor de "pi" a la variable shell
pi.
pi=$(echo "scale=10; 4*a(1)" | bc -l)
Lo siguiente es la definicion de la funcion exponencial usada en la
biblioteca matematica. Esta funcion esta escrita en bc de POSIX.
scale = 20
/* Usa el hecho de que e^x = (e^(x/2))^2
Si x es lo suficientemente pequeno, se usa la serie:
e^x = 1 + x + x^2/2! + x^3/3! + ...
*/
define e(x) {
auto a, d, e, f, i, m, v, z
/* Comprueba el signo de x. */
if (x<0) {
m = 1
x = -x
}
/* Precondicion x. */
z = scale;
scale = 4 + z + .44*x;
while (x > 1) {
f += 1;
x /= 2;
}
/* Inicializacion de las 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
}
}
El siguiente codigo usa las caracteristicas ampliadas de bc para
implementar un simple programa para calcular balances. Es mejor guardar
este programa en un fichero para poderlo usar varias veces sin tener
que teclearlo cada vez.
scale=2
print "\niPrograma de balances!\n"
print " Recuerde, los depositos son transacciones negativas.\n"
print " Para salir introducir una transaccion 0 .\n\n"
print "c Balance inicial ? "; bal = read()
bal /= 1
print "\n"
while (1) {
"Balance actual = "; bal
"c transaccion ? "; trans = read()
if (trans == 0) break;
bal -= trans
bal /= 1
}
quit
Lo siguiente es la definicion de la funcion factorial recursiva.
define f (x) {
if (x <= 1) return (1);
return (f(x-1) * x);
}
OPCI'ON READLINE
El bc de GNU se puede compilar (mediante una opcion de configuracion)
para usar la biblioteca de entrada readline de GNU. Esto permite al
usuario mayor posibilidad de edicion de las lineas antes de mandarlas a
bc. Tambien permite tener un historico de las lineas previamente
introducidas. Cuando se selecciona esta opcion, bc tiene una variable
especial mas. Esta variable especial, history es el numero de lineas
que se guardan en el historico. Un valor de -1 significa que este
numero es ilimitado. Este es el valor por defecto. Dando un valor
positivo a history se restringe el numero de lineas a este valor. El
valor 0 desactiva el historico. Para mas informacion, leer los manuales
de usuario de las bibliotecas readline y history de GNU.
DIFERENCIAS
Esta version de bc fue implementada a partir del borrador POSIX
P1003.2/D11 y contiene varias diferencias y ampliaciones respecto a
este borrador y las implementaciones tradicionales. No esta
implementada usando dc(1) como suele ser tradicional. Esta version es
un simple proceso que analiza el programa y ejecuta una traduccion de
este a un codigo de bytes (byte code). Hay una opcion "indocumentada"
(-c) que hace que el programa imprima en la salida estandar este codigo
en lugar de ejecutarlo. Fue usada principalmente para depurar el
analizador y preparar la biblioteca matematica.
Una mayor fuente de diferencias son las ampliaciones, tanto cuando son
anadidas para dar mas funcionalidad como cuando anaden nuevas
caracteristicas. Esta es la lista de las diferencias y ampliaciones.
Entorno LANG
Esta version no se ajusta al estandar POSIX sobre el proceso de
la variable de entorno LANG y todas las variables de entorno que
comienzan por LC_.
nombres
El bc tradicional y el de POSIX usan nombres de una sola letra
para funciones, variables y matrices. Han sido ampliados para
ser nombres multi-caracter que comienzan por una letra y pueden
contener letras, digitos y caracteres de subrayado.
Cadenas
No se permite que las cadenas contengan caracteres nulos (NUL).
El estandar POSIX dice que todos los caracteres se deben incluir
en las cadenas.
last En el bc de POSIX no existe la variable last. Algunas
implementaciones de bc usan el punto (.) de manera similar.
comparaciones
El bc de POSIX permite las comparaciones solo en la sentencia
if, la sentencia while y la segunda expresion de la sentencia
for. Ademas, solo se permite una operacion relacional en cada
una de estas sentencias.
sentencia if, clausula else
El bc de POSIX no tiene la clausula else.
sentencia for
El bc de POSIX obliga a que esten todas las expresiones de la
sentencia for.
&&, ||, !
El bc de POSIX no tiene los operadores logicos.
funcion read
El bc de POSIX no tiene la funcion read.
sentencia print
El bc de POSIX no tiene la sentencia print.
sentencia continue
El bc de POSIX no tiene la sentencia continue.
parametros de tipo matriz
El bc de POSIX (actualmente) no admite totalmente las matrices
como parametros. La gramatica POSIX permite incluir matrices en
la definicion de las funciones, pero no proporciona un metodo
para especificar una matriz como parametro en la llamada. (Se
puede considerar esto como un error de la gramatica). En las
implementaciones tradicionales de bc solo se pueden usar las
matrices como parametros por valor.
=+, =-, =*, =/, =%, =^
El bc de POSIX no define estos operadores de asignacion "al
viejo estilo". Esta version puede que las permita. Utilice la
sentencia limits para ver si la version instalada las admite. Si
se admiten, la sentencia "a =- 1" decrementara a en 1 en lugar
de asignar a a el valor -1.
espacios en los numeros
Otras implementaciones de bc permiten espacios en los numeros.
Por ejemplo, "x=1 3" asignaria a la variable x el valor 13. La
misma sentencia provocara un error de sintaxis en esta version
de bc.
errores y ejecucion
Esta implementacion varia de otras implementaciones en el tema
de que codigo se ejecutara cuando en el programa se encuentren
errores sintacticos o de otro tipo. Si en la definicion de una
funcion se encuentra un error sintactico, se intenta recuperar
el error encontrando el principio de la sentencia y continuando
con el analisis de la funcion. Una vez que el error se encuentra
en la funcion, la funcion no podra usarse y queda indefinida.
Los errores sintacticos en la ejecucion de codigo interactivo
invalidaran el actual bloque en ejecucion. El bloque en
ejecucion acaba con un salto de linea tras una secuencia
completa de sentencias. Por ejemplo,
a = 1
b = 2
tiene dos bloques y
{ a = 1
b = 2 }
tiene un bloque. Cualquier error en tiempo de ejecucion terminara con
el actual bloque en ejecucion. Un mensaje de aviso (warning) en tiempo
de ejecucion no terminara con el actual bloque en ejecucion.
Interrupciones
Durante una sesion interactiva, la senal SIGINT (habitualmente
generada por el caracter control-C desde el terminal) provocara
la interrupcion del actual bloque en ejecucion. Se mostrara un
error en tiempo de ejecucion indicando que funcion fue
interrumpida. Despues de limpiar todas las estructuras, se
muestra un mensaje al usuario para indicarle que bc esta listo
para aceptar mas entrada. Todas las funciones definidas
previamente permanecen definidas y las variables que no sean del
tipo auto conservan el valor que tenian en el momento de la
interrupcion. Durante una sesion no-interactiva, la senal SIGINT
interrumpira la ejecucion de bc por completo.
L'IMITES
Los limites actualmente en vigor para este procesador bc son los
siguientes. Algunos de ellos pueden haber cambiado en el proceso de
instalacion. Utilice la sentencia limits para ver sus valores actuales.
BC_BASE_MAX
La maxima base de salida se inicializa actualmente a 999. La
base maxima de entrada es 16.
BC_DIM_MAX
Tal y como se distribuye, este limite se inicializa
arbitrariamente a 65535. En su instalacion puede ser diferente.
BC_SCALE_MAX
El numero de digitos tras la coma decimal se limita a INT_MAX
digitos. De igual manera, el numero de digitos delante de la
coma decimal se limita a INT_MAX digitos
BC_STRING_MAX
El limite para el numero de caracteres de una cadena es INT_MAX
caracteres.
exponente
El valor del exponente en la operacion potencia (^) esta
limitado a LONG_MAX.
multiplicacion
La rutina de multiplicacion puede dar resultados incorrectos si
uno de los numeros tiene mas de LONG_MAX / 90 digitos en total.
Para enteros largos (longs) de 32 bits, este numero es
23.860.929 digitos.
tamano del codigo
Cada funcion y el programa principal ("main") estan limitados a
16384 bytes de codigo de bytes (byte code) cada uno. Este limite
(BC_MAX_SEGS) puede ser facilmente cambiado para tener mas de 16
segmentos de 1024 bytes.
nombres de variables
El limite actual para el numero de nombres unicos de variables
simples, matrices y funciones es de 32767 para cada tipo.
VARIABLES DE ENTORNO
Las siguientes variables de entorno son procesadas por bc:
POSIXLY_CORRECT
Esto es lo mismo que la opcion -s.
BC_ENV_ARGS
Este es otra forma de pasar argumentos a bc. El formato es el
mismo que los argumentos de la linea de comando. Estos
argumentos se procesan primero, por lo que cualquier fichero
presente en los argumentos de entorno es procesado antes que
cualquiera que aparezca en la linea de comando. Esto permite al
usuario establecer opciones "estandar" y los ficheros que seran
procesados en todas las invocaciones de bc. Los ficheros
listados en las variables de entorno generalmente contendran
definiciones de funciones que el usuario quiera tener definidas
cada vez que ejecute bc.
BC_LINE_LENGTH
Este es un numero que especifica el numero de caracteres
utilizados por los numeros en una linea en la salida. Incluyendo
los caracteres de contra-barra y de salto de linea para los
numeros largos.
FICHEROS
En la mayoria de las instalaciones, bc esta completamente auto-
contenido. Alli donde el tamano del ejecutable sea importante o el
compilador de C no maneje las cadenas muy largas, bc leera la
biblioteca matematica estandar del fichero /usr/local/lib/libmath.b.
(La situacion real puede variar. Puede ser /lib/libmath.b ).
DIAGN'OSTICOS
Si algun fichero dado en la linea de comando no se puede abrir, bc
informara que el fichero no esta disponible y terminara. Asimismo, hay
errores en tiempo de compilacion y de ejecucion que deberian ser auto-
explicativos.
FALLOS (BUGS)
La recuperacion de errores no es muy buena todavia.
Notifique cualquier error a bug-gnu-utils@prep.ai.mit.edu. Compruebe
que incluye la palabra ``bc'' dentro del campo ``Asunto:''
(``Subject:'').
AUTOR
Philip A. Nelson
phil@cs.wwu.edu
RECONOCIMIENTOS
El autor quisiera agradecer a Steve Sommars (Steve.Sommars@att.com) su
gran ayuda probando la implementacion. Me dio muchas sugerencias
estupendas. Este es un producto mejor gracias a su implicacion.
. bc(1)