You are on page 1of 19

Redondeo numrico y lenguajes de programacin Javier Goizueta 20012004

1. Funciones de redondeo
Existe cierta confusin sobre el funcionamiento de las distintas operaciones de conversin de nmeros no
enteros a enteros disponibles en algunos lenguajes de programacin. En este documento se trata de claricar
la situacin e introducir algunas subrutinas tiles para la programacin.
Veremos en primer lugar las funciones matemticas fundamentales que convierten nmeros reales en ente-
ros, y las distintas funciones disponibles para implementarlas en una seleccin de lenguajes de programacin.
Los lenguajes que consideraremos son:
C/C++: Funciones de las bibliotecas estndar
Ruby: Mdulos de la biblioteca estndar
Python: Mdulos de la biblioteca estndar
ECMAScript: Objetos nativos del estndar de JavaScript
Java: Clases del mdulo java.lang
C#: Bibliotecas del sistema .NET
Mathematica: Funciones incorporadas del sistema
RPL: Lenguaje User-RPL de las calculadoras HP (28, 48, 49)
Visual Basic: Funciones de Microsoft VB 6, VBA, VBScript
Fortran: Funciones intrnsecas de Fortran77
Pascal: Rutinas estndar de Object Pascal (Delphi/Kylix)
1.1. Entero inferior
La funcin oor, x|, a veces denotada [x], es el mayor entero menor o igual que x. Tambin es conocida por
el nombre francs entier.
C/C++: floor(x)
Ruby: x.floor
Python: math.floor(x)
ECMAScript: Math.floor(x)
Java: java.lang.Math.floor(x)
C# (.NET): System.Math.Floor(x)
Mathematica: Floor[x]
RPL: x FLOOR
Visual Basic: Int(x)
-3 -2 -1 1 2 3
-3
-2
-1
1
2
3
x|
1.2. Entero superior
La funcin ceiling, x| = x|, es el menor entero mayor o igual que x.
C/C++: ceil(x)
Ruby: x.ceil
Python: math.ceil(x)
ECMAScript: Math.ceil(x)
Java: java.lang.Math.ceil(x)
C# (.NET): System.Math.Ceiling(x)
Mathematica: Ceiling[x]
RPL: x CEIL
Visual Basic: -Int(-x)
-3 -2 -1 1 2 3
-3
-2
-1
1
2
3
x|
round.w 1 / 19
Redondeo numrico y lenguajes de programacin Javier Goizueta 20012004
1.3. Parte entera
sta es la funcin que devuelve la parte entera de un nmero: c(x) =

x| si x 0
x| si x < 0
Ruby: x.truncate = x.to_i
Mathematica: IntegerPart[x]
RPL: x IP
Visual Basic: Fix(x)
Pascal: Trunc(x)
Fortran: AINT(x)
-3 -2 -1 1 2 3
-3
-2
-1
1
2
3
c(x)
1.3.1. Parte fraccionaria
La parte fraccionaria es T(x) = x c(x).
Mathematica: FractionalPart[x]
RPL: x FP
Visual Basic: x-Fix(x)
Pascal: Frac(x)
-3 -2 -1 1 2 3
-1
-0.5
0.5
1
T(x)
1.4. Redondeo
Podemos denir diferentes funciones para calcular el entero ms cercano a un nmero segn cul sea el
tratamiento de los nmeros el conjunto / = {x| |T(x)| = 1/2} = {x|x + 1/2 Z}, ya que stos nmero son
equidistantes de los enteros inferior y superior ms cercanos.

+
(x) = x + 1/2|

(x) = x 1/2|

0
(x) =

x 1/2| si x 0
x + 1/2| si x < 0
(x)

(x) =

x + 1/2| = c(x + 1/2) si x 0


x 1/2| = c(x 1/2) si x < 0
Para evitar sesgos en el tratamiento de los nmeros de /, se suele usar en la prctima la regla de redondeo
conocidad como bancaria o gaussiana,
2
, segn la cual se redondean siempre los valores de /a nmeros
pares. De forma simtrica podemos denir una regla
1
que redondee / a nmeros impares:

2
(x) =

2
x+1/2
2
| si x /
(x) =
0
(x) =
+
=

si x , /

1
(x) =

2
x1/2
2
| + 1 si x /
(x) =
0
(x) =
+
=

si x , /
round.w 2 / 19
Redondeo numrico y lenguajes de programacin Javier Goizueta 20012004
Ruby: x.round= (x)
Python: round(x)= (x)
ECMAScript: Math.round(x)= (x)
Java: java.lang.Math.round(x)=
+
(x)
C# (.NET): System.Math.Round(x)=
2
(x)
Mathematica: Round[x]=
2
(x)
RPL (HP48,HP49): x 0 RND= (x)
Visual Basic: Round(x)=
2
(x)
Fortran: ANINT(x)= (x)
Pascal: Round(x)=
2
(x)
-4 -2 2 4
-4
-2
2
4
-4 -2 2 4
-4
-2
2
4

+
(x)

(x)
-4 -2 2 4
-4
-2
2
4
-4 -2 2 4
-4
-2
2
4

0
(x) (x)
-4 -2 2 4
-4
-2
2
4
-4 -2 2 4
-4
-2
2
4

2
(x)
1
(x)
1.4.1. Redondeo en un dgito determinado
Para redondear con ndgitos decimales podemos calcular
n
(x) = (10
n
x)/10
n
, y anlogamente,
2,n
(x),

0,n
(x),
,n
(x) y
+,n
(x).
round.w 3 / 19
Redondeo numrico y lenguajes de programacin Javier Goizueta 20012004
Python: round(x,n)=
n
(x)
C# (.NET): System.Math.Round(x,n)=
2,n
(x)
Mathematica: Round[x
*
10^n]/10^n=
2,n
(x)
RPL (HP48,HP49): x n RND=
n
(x)
Visual Basic: Round(x,n)=
2,n
(x)
Tambin puede ser necesario redondear con mdgitos de precisin. En este caso se deben contar estos dgitos
entre los ms signicativos de la cifra, en lugar de entre los decimales. Esto se puede lograr sencillamente
aplicando el redondeo con n dgitos decimales, siendo n = m 1 lg |x||. En algunos lenguajes, como RPL,
esta caracterstica est disponible empleando un nmero de dgitos negativos, m.
Igualmente podramos redondear en un dgito determinado de la expresin del valor en una base arbitraria
b:
b
n
(x) = (b
n
x)/b
n
, y anlogamente,
b
2,n
(x),
b
0,n
(x),
b
,n
(x) y
b
+,n
(x).
2. Programacin
Deniremos aqu algunas funciones de redondeo no presentes en algunos lenguajes. Podemos calcular
cualquiera de las funciones ms interesantes de redondeo disponiendo nicamente de la funcin x|:
x| = x|
c(x) =

x| si x 0
x| si x < 0
T(x) = x c(x)

+
(x) = x + 1/2|

(x) = x 1/2|

0
(x) =

x 1/2| si x 0
x + 1/2| si x < 0
(x) =

x + 1/2| si x 0
x 1/2| si x < 0
/ = {x|x| + 1/2 = x}

2
(x) =

2
x+1/2
2
| si x /
x + 1/2| si x , /
Si no se dispone de la funcin x|, se puede calcular esta, (y por tanto todas las dems), empleando c(x) o
en general cualquier funcin f(x) tal que x 0, f(x) = x|
x| =

f(x) si x 0
f (f(x) + 1 + x) f(x) 1 si x < 0
Para cualquiera de las funciones f de redondeo podemos calcular una funcin f
n
que aplique el redondeo
al dgito decimal n, y, con ms generalidad, una funcin f
k
que redonde a un mltiplo de k. (tendremos que
f
n
(x) = f
10
n

).
f
n
(x) = f(10
n
x)/10
n
f
k
= kf(x/k)
Tambin podemos denir una funcin f
m
que aplique el redondeo f al dgito signicativo m as:
f
m
(x) = f
m1lg |x|
(x)
round.w 4 / 19
Redondeo numrico y lenguajes de programacin Javier Goizueta 20012004
2.1. Visual Basic
El lenguaje Visual Basic carece de una funcin de redondeo hacia innito (x). Deniremos una funcin
RoundI para ello.
El valor que deseamos calcular es Fix(x
*
10^d+0.5
*
Sgn(x))/10^d, pero trataremos de lograr una ma-
yor eciencia:
"vb/roundi.bas" 5a
Public Function RoundI(ByVal x As Double, Optional ByVal d As Integer = 0) As Double
Dim m As Double
m = 10^d
If x < 0 Then
RoundI = Fix(x
*
m - 0.5) / m
Else
RoundI = Fix(x
*
m + 0.5) / m
End If
End Function
3
Nota: Muchos programas emplean la expresin Int(x+0.5) para realizar redondeos en Visual Basic; esto
equivale a la funcin
+
(x).
2.2. C++
Las siguientes funciones estn escritas en C++, pero es muy sencillo traducirlas a C.
"c/round.h" 5b
#ifndef ROUNDING_H
#define ROUNDING_H
namespace rounding {
Declaraciones de funciones de redondeo 5d, . . .
};
#endif
3
"c/round.cpp" 5c
#include "round.h"
namespace rounding {
Deniciones de funciones de redondeo 5e, . . .
};
3
Deniremos dos funciones en C++ para calcular c(x) y T(x).
Declaraciones de funciones de redondeo 5d
double integer_part(double);
double fractional_part(double);
3
Fragmento denido en 5d, 6bd.
Fragmento usado en 5b.
sta es la funcin c(x), que equivale a (x<0) ? std::ceil(x) : std::floor(x).
Deniciones de funciones de redondeo 5e
double integer_part(double x) // (x<0) ? std::ceil(x) : std::floor(x)
{
static double y;
std::modf(x,&y);
return y;
}
3
Fragmento denido en 5e, 6ace.
Fragmento usado en 5c.
round.w 5 / 19
Redondeo numrico y lenguajes de programacin Javier Goizueta 20012004
Y sta, T(x), y equivale a x-integer_part(x).
Deniciones de funciones de redondeo 6a
double fractional_part(double x) // x-integer_part(x)
{
static double y;
return std::modf(x,&y);
}
3
Fragmento denido en 5e, 6ace.
Fragmento usado en 5c.
Las bibliotecas estndar de C y C++ carecen de funciones de redondeo. Deniremos aqu las ms usadas.
En primer lugar, (x).
Declaraciones de funciones de redondeo 6b
double round_inf(double x, int d=0);
3
Fragmento denido en 5d, 6bd.
Fragmento usado en 5b.
Deniciones de funciones de redondeo 6c
double round_inf(double x, int d)
{
if (d==0)
return x < 0.0 ? std::ceil(x-0.5) : std::floor(x+0.5);
double m = std::pow(10.0,d);
return x<0.0 ? std::ceil(x
*
m-0.5)/m : std::floor(x
*
m-0.5)/m;
}
3
Fragmento denido en 5e, 6ace.
Fragmento usado en 5c.
Implementaremos tambin el redondeo bancario
2
(x) =

2
x+1/2
2
| si x /
x + 1/2| si x , /
Declaraciones de funciones de redondeo 6d
double round_unbiased(double x, int d=0);
3
Fragmento denido en 5d, 6bd.
Fragmento usado en 5b.
Deniciones de funciones de redondeo 6e
double round_unbiased(double x, int d)
{
double m = pow(10.0,d);
x
*
= m;
x += 0.5;
x = (fractional_part(x)==0.0) ? 2.0
*
std::floor(x
*
0.5) : std::floor(x);
return x/m;
}
3
Fragmento denido en 5e, 6ace.
Fragmento usado en 5c.
Tambin podramos haber usado nicamente la funcin floor as:
round.w 6 / 19
Redondeo numrico y lenguajes de programacin Javier Goizueta 20012004
Alternativa sin fractional_part 7a
double round_unbiased(double x, int d)
{
double m = pow(10.0,d);
x
*
= m;
x += 0.5;
double y = std::floor(x);
x = (x==y) ? 2.0
*
std::floor(x
*
0.5) : y;
return y/m;
}
3
Fragmento no usado.
2.3. Mathematica
Las funciones (x),
+
(x),

(x),
0
(x) y
1
(x) no estn presentes en Mathematica, y las deniremos
aqu.
La funcin RoundUp[x] implementa
+
(x):
"math/round.m" 7b
RoundUp[x_] := Floor[x + 0.5]
3
Archivo denido en 7bcdefg, 8abcdefg, 9abcde.
La funcin RoundUp[x] implementa

(x):
"math/round.m" 7c
RoundDn[x_] := Ceiling[x - 0.5]
3
Archivo denido en 7bcdefg, 8abcdefg, 9abcde.
La funcin RoundZero[x] implementa
0
(x):
"math/round.m" 7d
RoundZero[x_] := If[x < 0, RoundUp[x], RoundDn[x]]
3
Archivo denido en 7bcdefg, 8abcdefg, 9abcde.
La funcin RoundInf[x] implementa (x):
"math/round.m" 7e
RoundInf[x_] := If[x < 0, RoundDn[x], RoundUp[x]]
3
Archivo denido en 7bcdefg, 8abcdefg, 9abcde.
La funcin RoundOdd[x] implementa
1
(x):
"math/round.m" 7f
RoundOdd[x_] := If[Floor[x]+0.5==x, 2Floor[(x-0.5)
*
0.5]+1,Floor[x+0.5]]
3
Archivo denido en 7bcdefg, 8abcdefg, 9abcde.
Deniremos aqu tambin las subrutinas empleadas para generar las ilustraciones de este documento.
En primer lugar, una funcin Fplot para generar el grco de una funcin entre dos valores de su variable
libre:
"math/round.m" 7g
Fplot[f_, x1_, x2_] := Plot[f[x], {x, x1, x2}]
3
Archivo denido en 7bcdefg, 8abcdefg, 9abcde.
round.w 7 / 19
Redondeo numrico y lenguajes de programacin Javier Goizueta 20012004
Y otra funcin Pplot para marcar una serie de puntos discretos de esa funcin. Los puntos se tomarn en los
valores enteros entre x1 y x2, pero desplazados en una cantidad d. De esta forma podremos marcar los puntos
del conjunto /, haciendo d= 1/2.
"math/round.m" 8a
Pplot[f_, x1_, x2_, d_] := ListPlot[Table[{x + d, f[x + d]}, {x, x1, x2}]]
3
Archivo denido en 7bcdefg, 8abcdefg, 9abcde.
Por ltimo, la funcin ShowF nos permitir combinar ambos grcos seleccionando un tamao adecuado para
los puntos. Los argumentos de este procedimiento sern la funcin f a visualizar, los extremos para los valores
de la funcin y los extremos y desplazamiento para los puntos discretos.
"math/round.m" 8b
ShowF[f_, x1_, x2_, n1_, n2_, d_] :=
Show[Fplot[f, x1, x2], Pplot[f, n1, n2, d],
Prolog -> AbsolutePointSize[5]]
3
Archivo denido en 7bcdefg, 8abcdefg, 9abcde.
Los grcos que aparecen en este documento han sido generados con las siguientes instrucciones:
Funcin x|:
"math/round.m" 8c
ShowF[Floor, -3, 3.1, -3, 3, 0]
3
Archivo denido en 7bcdefg, 8abcdefg, 9abcde.
Funcin x|:
"math/round.m" 8d
ShowF[Ceiling, -3.1, 3, -3, 3, 0]
3
Archivo denido en 7bcdefg, 8abcdefg, 9abcde.
Funcin c(x):
"math/round.m" 8e
ShowF[IntegerPart, -3.1, 3.1, -3, 3, 0]
3
Archivo denido en 7bcdefg, 8abcdefg, 9abcde.
Funcin T(x):
"math/round.m" 8f
ShowF[FractionalPart, -3.1, 3.2, -3, 3, 0]
3
Archivo denido en 7bcdefg, 8abcdefg, 9abcde.
Funcin
2
(x):
"math/round.m" 8g
ShowF[Round, -4.5, 4.5, -5, 4, 0.5]
3
Archivo denido en 7bcdefg, 8abcdefg, 9abcde.
Funcin
1
(x):
round.w 8 / 19
Redondeo numrico y lenguajes de programacin Javier Goizueta 20012004
"math/round.m" 9a
ShowF[RoundOdd, -4.5, 4.5, -5, 4, 0.5]
3
Archivo denido en 7bcdefg, 8abcdefg, 9abcde.
Funcin
+
(x):
"math/round.m" 9b
ShowF[RoundUp, -4.5, 4.5, -5, 4, 0.5]
3
Archivo denido en 7bcdefg, 8abcdefg, 9abcde.
Funcin

(x):
"math/round.m" 9c
ShowF[RoundDn, -4.5, 4.5, -5, 4, 0.5]
3
Archivo denido en 7bcdefg, 8abcdefg, 9abcde.
Funcin
0
(x):
"math/round.m" 9d
ShowF[RoundZero, -4.5, 4.5, -5, 4, 0.5]
3
Archivo denido en 7bcdefg, 8abcdefg, 9abcde.
Funcin (x):
"math/round.m" 9e
ShowF[RoundInf, -4.5, 4.5, -5, 4, 0.5]
3
Archivo denido en 7bcdefg, 8abcdefg, 9abcde.
2.4. RPL
La versin de RPL referida aqu es la de las calculadoras de las series 48 y 49, que tienen una funcin RND
con dos argumentos: el nmero a redondear y la precisin. La serie 28 tena una instruccin RND con un nico
argumento (el nmero a redondear) que redondeaba en base al modo numrico actual (STD, FIX, ENG).
Incluiremos los programas de RPL descritos aqu en un directorio:
"round.rpl" 9f
%%HP: T(3)A(D)F(.);
DIR
Objetos RPL 10a, . . .
END
3
Este primer programa calcula el redondeo
2
(x) =

2
x+1/2
2
| si x /
x + 1/2| si x , /
round.w 9 / 19
Redondeo numrico y lenguajes de programacin Javier Goizueta 20012004
Objetos RPL 10a
RNDI0
\<<
.5 +
IF DUP FP 0 == THEN
.5
*
FLOOR 2
*
ELSE
FLOOR
END
\>>
3
Fragmento denido en 10abc.
Fragmento usado en 9f.
Si queremos redondear a un nmero de dgitos dado, podemos emplear el siguiente programa, introdu-
ciendo en la pila en primer lugar el nmero a redondear y en segundo lugar el nmero de decimales.
Objetos RPL 10b
RNDIN
\<<
ALOG SWAP OVER
*
RNDI0
SWAP /
\>>
3
Fragmento denido en 10abc.
Fragmento usado en 9f.
La instruccin RND de RPL puede redondear adems con un nmero dado de dgitos de precisin, en lugar de
dgitos decimales. Esto lo hace cuando el nmero de dgitos establecido es negativo. Realizaremos un programa
RNDI que haga lo mismo, pero con el redondeo
2
.
Objetos RPL 10c
RNDI
\<<
IF DUP 0 < THEN
NEG OVER ABS LOG FLOOR 1 + -
END
ALOG SWAP OVER
*
RNDI0
SWAP /
\>>
3
Fragmento denido en 10abc.
Fragmento usado en 9f.
Las calculadoras RPL (HP28, HP48 y HP49) redondean internamente los resultados de las operaciones aritmti-
cas en coma otante mediante
12
2
(x) (a 12 dgitos signicativos). El siguiente programa usa esta caracterstica
para implementar
2,n
(x)
\<<
11 SWAP - ALOG OVER SIGN
*
DUP ROT + SWAP -
\>>
Por ltimo, este programa reproduce la funcin RND de HP48 y HP49, y puede ser til como comando
unicado que tambin funciona en HP28.
round.w 10 / 19
Redondeo numrico y lenguajes de programacin Javier Goizueta 20012004
"round28.rpl" 11
%%HP: T(3)A(D)F(.);
ROUND
\<<
IF DUP 0 < THEN
NEG OVER ABS LOG FLOOR 1 + -
END
ALOG SWAP OVER
*
IF DUP 0 < THEN
.5 - CEIL
ELSE
.5 + FLOOR
END
SWAP /
\>>
3
2.4.1. Redondeo interno en calculadoras HP
Las calculadoras de 10 dgitos como la HP-35, HP-15c, HP-16c usan un redondeo intero del tipo (x). En
este ejemplo el nmero 1000000000,5 se redondea a 1000000001:
1 EEX 9 0.5 + -> 1000000001
La representacin en pantalla en los modos FIX, SCI, ENG cuandor requiere redondeo utiliza tambin una
funcin del tipo
\
(x). En el caso de la funcin RND de la 15c se utiliza el mismo redondeo usado en la
visualizacin.
Las calculadoras HP de 12 dgitos, como las series 28, 48, 49, 50 (RPL), las 32s, 42s (RPL internamente)
o las 33s, 35s, usan un redondeo interno
2
(x) de forma que 100000000000,5 se redondea a 100000000000 y
100000000001,5 a 100000000002:
1 EEX 11 0.5 + -> 100000000000
1 EEX 11 1 + 0.5 + -> 100000000002
Pero en estas mismas calculadoras el redondeo usado para los modod de visualizacin FIX, SCI, ENG y
para la funcin RND es del tipo
n
(x).
Las calculadoras de las series 48 y 49 usan internamente nmeros de 15 dgitos (reales extendidos) que no son
redondeados sino truncados (adems el resultado de algunas funciones internas es inexacto hasta en los dos
ltimos dgitos). Los resultados nales se convierten al formato normal (real) de 12 dgitos mediante redondeo

2
.
Los nmeros de precisin extendida pueden emplearse programando en SysRPL o mediante la biblioteca
XREAL (1005). Estos nmeros son tiles para realizar clculos y almacenar los resultados intermedios, de
forma similar a los registros de 80 bits de la implementacin de coma otante IEEE de los procesadores INTEL.
Por ejemplo podramos programar una funcin para logaritmos en base arbitraria usando XREAL as:
\<< R~X SWAP R~X XLN SWAP XLN XDIV R~X \>>
Obteniendo una mayor precisin que mediante su equivalente LN SWAP LN SWAP /.
La calculador aHP-15C cuenta con las operaciones:
x INT = c(x)
x FRAC= T(x)
x RND=
n
(x) con n segn el modo de visualizacin actual.
La calculadora HP-35s tiene estas operaciones:
x IP = c(x)
x FP= T(x)
x RND=
n
(x) con n segn el modo de visualizacin actual (notar que internamente en cambio se usa
el redondeo
2,15
(x))
round.w 11 / 19
Redondeo numrico y lenguajes de programacin Javier Goizueta 20012004
2.4.2. LONGFLOAT
Tambin hay disponible una biblioteca para las serie 49, LONGFLOAT (902), que trabaja con nmeros
de precisin arbitraria (jada por una variable DIGITS). Un nmero x se representa mediante un exponente
decimal y una mantisa entera de d = DIGITS digitos cuyo valor y es:
y = 10
d
x
10
log |x|+1
Se cuenta con cuatro modos de redondeo que se aplican a y en funcin del estado de los indicadores 37 y 38
del sistema y son similares a las especicadas en IEEE 754:
al ms cercano ((y)): -37 CF -38 CF
hacia abajo (y|): -37 SF -38 CF
hacia arriba (y|): -37 CF -38 SF
truncado hacia cero c(y): -37 SF -38 SF
Pero este redondeo se hace teniendo nicamente en cuenta el dgito siguiente al dgito redondeado, por lo
que slo se realiza correctamente en el primer caso ((y)).
La versin 3.5 cambia el redondeo al ms cercano por redondeo a par
2
(x); se sigue usando ni-
camente un dgito adicional. La versin 3.93 se distribuye en dos opciones, (y) y
2
(x), esta ltima con el
defecto mencionado.
round.w 12 / 19
Redondeo numrico y lenguajes de programacin Javier Goizueta 20012004
3. Otros lenguajes y sistemas
3.1. SQL
El lenguaje Transact-SQL, o T-SQL es la versin de SQL implementada por Microsoft SQL Server (original-
mente Sybase). Estas funciones no estn en el estndar de SQL.
FLOOR(x)= x|
CEILING(x)= x|
ROUND(x,n)=ROUND(x,n,0)= (10
n
x)/10
n
ROUND(x,n,1)= c(10
n
x)/10
n
(el tercer parmetro indica truncamiento)
Los dialectos SQL de PostgreSQL, MySQL y Oracle tienen estas mismas funciones, excepto la versin de
ROUND de tres parmetros. Adems la funcin CEILING anterior se puede usar con la denominacin CEIL.
3.2. MapBasic
El lenguaje MapBasic es el lenguaje del sistema MapInfo.
Int(x)= x|
Fix(x)= c(x)
Round(x,y) =

y
+
(x/y) si y ,= 0
x si y = 0
3.3. Excel
Aqu nos referimos al lenguaje de frmulas de Microsoft Excel, no al lenguaje de macros que incorpora,
VBA (Visual Basic for Applications).
Los nombres de las funciones son distintos en versiones de Excel para diferentes idiomas. Se muestran los
nombres en ings y castellano.
ROUND(x,n)REDONDEAR(x,n) =
n
(x)
ROUNDUP(x,n)REDONDEAR.MAS(x,n) =

(10
n
x)|/10
n
si x 0
(10
n
x)|/10
n
si x < 0
ROUNDDOWN(x,n)REDONDEAR.MENOS(x,n) = c(10
n
x)/10
n
=

(10
n
x)|/10
n
si x 0
(10
n
x)|/10
n
si x < 0
EVEN(x)REDONDEA.PAR(x)=2
*
ROUNDUP(x/2,0) =

2x/2| si x 0
2x/2| si x < 0
ODD(x)REDONDEA.IMPAR(x) =

2(x + 1)/2| 1 si x 0
2(x 1)/2| + 1 si x < 0
INT(x)ENTERO(x)= x|
TRUNC(x,n)TRUNCAR(x,n)=ROUNDDOWN(x,n)
FLOOR(x,y)MULTIPLO.INFERIOR(x,y)= y(x/y)|
CEILING(x,y)MULTIPLO.SUPERIOR(x,y)= y(x/y)|
MROUND(x,y)REDOND.MULT(x,y)=y
*
ROUND(x/y,0)= y(x/y)
Excel introduce tres funciones cuya forma no ha sido mostrada en la primera seccin de este documento:
round.w 13 / 19
Redondeo numrico y lenguajes de programacin Javier Goizueta 20012004
-3 -2 -1 1 2 3
-4
-2
2
4
-4 -2 2 4
-6
-4
-2
2
4
6
-4 -2 2 4
-4
-2
2
4
ROUNDUP(x,0) EVEN(x) ODD(x)
3.4. PHP
floor(x)= x|
ceil(x)= x|
round(x,n)==
n
(x) a partir de la versin 4
round(x)=round(x,0)= (x)
3.5. MatLab
floor(x)= x|
ceil(x)= x|
fix(x)= c(x)
round(x)= (x) sin vericar; podra ser
2
3.6. MathCAD
round(x,n)=
n
(x) en algunas versiones, (e.g. 8.00-8-02),
2,n
(x)
round(x)=round(x,0)
floor(x)= x|
ceil(x)= x|
trunc(x)= c(x)
mantissa(x)=x-floor(x)
round(x)=round(x,0)= (x)
3.7. Maple
floor(x)= x|
ceil(x)= x|
trunc(x)= c(x)
frac(x)= T(x)
round(x)= (x)
round.w 14 / 19
Redondeo numrico y lenguajes de programacin Javier Goizueta 20012004
3.8. Scheme
(round x)=
2
(x) algunas implementaciones no estndar, como KSM, usan (x)
(floor x)= x|
(ceiling x)= x|
(truncate x)= c(x)
3.8.1. Common Lisp
De forma similar a como ocurre en Fortran con el prejo A, (AINT,ANINT vs. INT,NINT), Las siguientes fun-
ciones con el prejo f devuelven valores en coma otante, mientras que las funciones sin este prejo devuelven
valores de tipo entero.
(fround x)= (x) sin vericar
(ffloor x)= x|
(fceiling x)= x|
(ftruncate x)= c(x)
3.9. Perl
int(x)= c(x)
Podemos emplear calcular (x)=int(x+.5*(x<=>0)) . Por ejemplo:
"round.perl" 15
sub round {
my($number) = shift;
return int($number + .5
*
($number <=> 0));
}
3
A partir de la versin 5, se incluye un mdulo POSIX que contiene las funciones:
floor(x)= x|
ceil(x)= x|
3.10. IEEE 754
El estndard de coma otante IEEE 754 especica 4 modos de redondeo que son tiles para acotacin de
errores, comprobacin de la estabilidad de los clculos, implementacin de aritmtica de intervalos, etc. Estos
redondeos (de los cuales slo el modo por defecto es un redondeo en el sentido denido aqu de ajuste al valor
ms cercano y los otros se denominan redondeos orientados directed) se aplican al dgito menos signicativo
de los resultados de operaciones aritmticas que se calculan internamente con mayor precisin.
Los modos denidos por el estndar, para una base b arbitraria (en IEEE 754 b = 2) y n como posicin del
dgito menos signicativo, son:
round to nearest:
b
2,n
(x) (round to even)
round toward +: xb
n
|/b
n
(round up)
round toward : xb
n
|/b
n
(round down)
round toward 0: cxb
n
/b
n
(truncate)
round.w 15 / 19
Redondeo numrico y lenguajes de programacin Javier Goizueta 20012004
3.10.1. IEEE 754r
La revisin del estndar especica otros nombres para los modos de redondeo y se aade un nuevo modo
de redondeo.
roundTiesToEven:
b
2,n
(x)
roundTiesToAway:
b
n
(x) =
b
,n
(x)
roundTowardPositive: xb
n
|/b
n
roundTowardNegative: xb
n
|/b
n
roundTowardZero: cxb
n
/b
n
3.11. Coprocesadores numricos Intel
Los procesadores 8087, 80287,i387, i486, Pentium, etc., se ajustan a las normas de coma otante IEEE y
realizan un redondeo en el bit menos signicativo en las operaciones aritmticas controlado por los bits 10 y
11 de la palabra de control del coprocesador:
00 (round to nearest):
b
2,n
(x)
01 (round toward ): xb
n
|/b
n
10 (round toward +): xb
n
|/b
n
11 (round toward 0): cxb
n
/b
n
La instruccin FRNDINT converte un valor a entero en funcin del modo de redondeo:
modo 00 (round to nearest)
2
(x)
modo 01 (round toward ) x|
modo 10 (round toward +) x|
modo 11 (round toward 0 c(x)
3.12. C/C++
3.12.1. C99
Las bibliotecas de C99 incluyen control del mtodo de redondeo en <fenv.h> acordes al estndar IEEE y
funciones de redondeo en <tgmath.h> y <math.h>.
fsetround(FE_DOWNWARD);nearbyint(x)=rint(x)= x|
fsetround(FE_UPWARD);nearbyint(x)=rint(x)= x|
fsetround(FE_TONEAREST);nearbyint(x)=rint(x)=
2
(x)
fsetround(FE_TOWARDZERO);nearbyint(x)=rint(x)= c(x)
round(x)= (x)
trunc(x)= c(x)
3.12.2. C90
En C90 (C89), hay un valor denido en <float.h> que indica el modo de redondeo para la suma en coma
otante:
FLT_ROUNDS-1(indeterminado)
FLT_ROUNDS0c(x)
FLT_ROUNDS1(x) (o bien otro redondeo al entero ms cercano)
FLT_ROUNDS2x|
FLT_ROUNDS3x|
round.w 16 / 19
Redondeo numrico y lenguajes de programacin Javier Goizueta 20012004
3.12.3. C++
En C++, este mismo valor est denido en <limits>, en std::numeric_limits<...>::round_style
std::round_indeterminable-1(indeterminado)
std::round_toward_zero0c(x)
std::round_to_nearest1(x) (u otro redondeo)
td::round_toward_infinity2x|
std::round_toward_neg_infinity3x|
3.13. General Decimal Arithmetic Specication
Existe un contexto que contiene parmetros y reglas que afectan a los resultados de las operaciones. Uno de
los parmetros es el modo de redondeo (rounding) que indica el algoritmo que se usa para ajustar la precisin
de los resultados, y que puede tomar los siguiente valores:
round-half-even=
2,n
(x) (em round to nearest, ties to even)
round-half-up=
n
(x) =
,n
(x) (round to nearest, ties away from zero)
round-half-down=
0,n
(x) ) opcional
round-up =

(10
n
x)|/10
n
si x 0
(10
n
x)|/10
n
si x < 0
round away from zero opcional
round-down = c(10
n
x)/10
n
=

(10
n
x)|/10
n
si x 0
(10
n
x)|/10
n
si x < 0
(round toward zero, truncate)
round-ceiling= 10
n
x|/10
n
(round toward +)
round-oor= 10
n
x|/10
n
(round toward )
La especicacin dene una funcin para aplicar el redondeo denido por el contexto; por ejemplo si el
redondeo es round-half-up: quantize(x, y) =
n
(x) con n igual al exponente de y; si y es normalizado se tiene
n = log
10
y|. Lo habitual es emplear potencias de 10 para y:
n
(x) = quantize(10
n
).
Inicialmente se haba denido una funcin equivalente con otra forma de especicar el nmero de dgitos:
rescale(x, n) =
n
(x)
3.14. Ruby BigDecimal
La clase BigDecimal (incluida con Ruby, versin 1.8 y posteriores) tiene varios mtodos y opciones de
redondeo.
x.round(n,BigDecimal::ROUND_HALF_UP)=
n
(x)
x.round(n,BigDecimal::ROUND_HALF_EVEN)=
2,n
(x)
El modo de redondeo ROUND_HALF_DOWN es una versin defectuosa de
0
, ya que slo se tiene en cuenta
el dgito siguiente al dgito redondeado (entendiendo por tal el dgito menos signicativo mostrado despus
del redondeo, que puede haber sido ajustado). Si el dgito a redondear es 5 (o inferior), se redondea el valor
hacia cero, aunque haya otros dgitos no nulos detrs de l. Si el dgito es 6 (o superior) se redondea hacia
innito.
Nota: en las ltimas pruebas con Ruby 1.8.6, tambin ROUND_HALF_EVEN presenta este comportamiento
anmalo.
Los siguientes modos de redondeo no son propiamente redondeos, corresponden a los modos del estndar
IEEE y permiten la implementacin de aritmtica de intervalos; (las funciones tercera y cuarta corresponden a
ROUNDUP y ROUNDDOWN de Excel.
x.round(n,BigDecimal::ROUND_CEILING)=x.ceil(n)= 10
n
x|/10
n
round.w 17 / 19
Redondeo numrico y lenguajes de programacin Javier Goizueta 20012004
x.round(n,BigDecimal::ROUND_FLOOR)=x.floor(n)= 10
n
x|/10
n
x.round(n,BigDecimal::ROUND_UP) =

(10
n
x)|/10
n
si x 0
(10
n
x)|/10
n
si x < 0
x.round(n,BigDecimal::ROUND_DOWN) = c(10
n
x)/10
n
=

(10
n
x)|/10
n
si x 0
(10
n
x)|/10
n
si x < 0
Como hemos visto, las funciones floor, ceil tambin admiten un parmetro opcional (con valor 0 por
omisin) para especicar el dgito sobre el que se opera.
El modo de redondeo por omisin se puede establecer con BigDecimal::mode; el valor inicial por omi-
sin es ROUND_HALF_UP ().
BigDecimal::mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_UP)
BigDecimal::mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_DOWN)
BigDecimal::mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_UP)
BigDecimal::mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_DOWN)
BigDecimal::mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN)
BigDecimal::mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_CEILING)
BigDecimal::mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_FLOOR)
Este modo de redondeo se usa tambin para el redondeo interno, el que ocurre por ejemplo en la expresin:
BigDecimal(.1E15).add(BigDecimal(0.5),15)
La posicin decimal a redondear es tambin opcional; el valor por omisin es 0. Si el modo de redondeo
por omisin inicial no se ha modicado, tedremos que:
x.round= (x)
Otros mtodos:
x.fix= c(x)
x.frac= T(x)
x.truncate= c(x)
x.truncate(n)= c(10
n
x)/10
n
Nota: to_i da el mismo resultado que fix, pero en forma de nmero entero (Integer) en lugar de
BigDecimal.
3.15. Python Decimal
El tipo Decimal de Python est regido por la General Decimal Arithmetic Specication.
Los modos de redondeo (asignados por ejemplo mediante getcontext().rounding=ROUND_HALF_EVEN
son los siguientes:
ROUND_CEILING=x.ceil(n)= 10
n
x|/10
n
ROUND_DOWN = c(10
n
x)/10
n
=

(10
n
x)|/10
n
si x 0
(10
n
x)|/10
n
si x < 0
ROUND_FLOOR=x.floor(n)= 10
n
x|/10
n
ROUND_HALF_UP)=
n
(x)
ROUND_HALF_EVEN=
2,n
(x)
ROUND_HALF_DOWN=
0,n
(x)
ROUND_UP =

(10
n
x)|/10
n
si x 0
(10
n
x)|/10
n
si x < 0
round.w 18 / 19
Redondeo numrico y lenguajes de programacin Javier Goizueta 20012004
El contexto aritmtico contiene adems del modo de redondeo y otros parmetros la precisin (nmero de
decimales) de las operaciones y conversiones. Los modos de redondeo se utilizan en todas las operaciones, de
forma que el resultado equivale a realizar la operacin de forma exacta y despus redondearlo mediante el
modo y precisin establecidos en el contexto. El modo de redondeo no se emplean tambin en la conversin
de literales de texto a nmeros.
El modo de redondeo inicial por omisin es ROUND_HALF_EVEN (
2
) y la precisin 28.
Hay una funcin genrica de redondeo, quantize que se puede usar con cualquiera de los modos:
x.quantize(y, rounding=ROUND_HALF_EVEN)=
2,n
con y=Decimal(10)
**
(-n) (y = 10
n
) o,
con ms generalidad n=y.as_tuple()[2] (n es el exponente de y). Si y es un valor normalizado, entonced
n = log
10
y|.
round.w 19 / 19

You might also like