Discussion:
Redondeando un float al int mas cercano
(demasiado antiguo para responder)
Eduardo
2005-01-07 13:20:38 UTC
Permalink
En una asignacion comun los trunca, hay funciones (ceil y floor) para
redondeos hacia arriba y hacia abajo, pero y al mas cercano?

La palabra de control del procesador matematico esta configurada siempre
para redondear al mas cercano, en una asignacion flot -> int corriente
llama a la rutina _ftol que cambia la palabra de control , ejecuta un FISTP
(lo unico que habia que hacer) y luego restaura el estado :-( , no hay
alguna opcion de compilacion para que asuma por defecto el redondeo al mas
cercano?

Saludos.
Eduardo.

PD. por si alguno no se dio cuenta, cada vez que no entiendo algo en C
recurro al listado en assembler, cada uno usa las herramientas que conoce
mejor...
sés
2005-01-07 13:41:11 UTC
Permalink
Post by Eduardo
En una asignacion comun los trunca, hay funciones (ceil y floor) para
redondeos hacia arriba y hacia abajo, pero y al mas cercano?
int round( float f )
{
return (int)(f + 0.5);
}
--
sés
Eduardo
2005-01-07 14:55:05 UTC
Permalink
Post by sés
Post by Eduardo
En una asignacion comun los trunca, hay funciones (ceil y floor) para
redondeos hacia arriba y hacia abajo, pero y al mas cercano?
int round( float f )
{
return (int)(f + 0.5);
}
Escribiendo la rutina no tiene gracia ;-) ( ademas si es negativo habria
que restar 0.5 ).
Puedo poner #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))

Pero me parece absurdo tener que escribir una funcion o un macro cuando lo
'natural' seria escribir:

int N; float p=3.6;
...................
N = 3*p ; // y N tome el valor 11

Y digo 'absurdo' porque es como si tuviera que escribir una rutina para
incrementar un entero.


Saludos.
Eduardo.
Carlos
2005-01-07 15:03:55 UTC
Permalink
Post by sés
Post by Eduardo
En una asignacion comun los trunca, hay funciones (ceil y floor) para
redondeos hacia arriba y hacia abajo, pero y al mas cercano?
int round( float f )
{
return (int)(f + 0.5);
}
¿Y los negativos?

round(-4.9) -> -4

Suerte.
sés
2005-01-10 09:14:45 UTC
Permalink
Post by Carlos
¿Y los negativos?
^_^'
--
sés
Lepton
2005-01-07 23:41:26 UTC
Permalink
On Fri, 7 Jan 2005, Eduardo wrote:

# En una asignacion comun los trunca, hay funciones (ceil y floor) para
# redondeos hacia arriba y hacia abajo, pero y al mas cercano?
#
# La palabra de control del procesador matematico esta configurada siempre
# para redondear al mas cercano, en una asignacion flot -> int corriente
# llama a la rutina _ftol que cambia la palabra de control , ejecuta un FISTP
# (lo unico que habia que hacer) y luego restaura el estado :-( , no hay
# alguna opcion de compilacion para que asuma por defecto el redondeo al mas
# cercano?

Veo que ya te han contestado por ahi, pero tambien merece la pena
mirar si en tu sistema existe la funcion 'rint' (tambien 'nearbyint'),
o 'round' (ese forma parte del standard C99).

Lepton.
Eduardo
2005-01-08 12:00:31 UTC
Permalink
Post by Lepton
Veo que ya te han contestado por ahi, pero tambien merece la pena
mirar si en tu sistema existe la funcion 'rint' (tambien 'nearbyint'),
o 'round' (ese forma parte del standard C99).
Lepton.
Ninguna de las dos, uso el CBuilder.
Mi duda era si existia algun tipo de declaracion para que asuma como
redondeo por defecto el entero mas cercano, uno cree que todo lo bello
deberia existir.

Saludos.
Eduardo.
Lepton
2005-01-09 00:33:10 UTC
Permalink
On Sat, 8 Jan 2005, Eduardo wrote:

# "Lepton" <***@jazzfree.com> escribió en el mensaje
# news:***@ID-130846.user.uni-berlin.de...
# >
# > Veo que ya te han contestado por ahi, pero tambien merece la pena
# > mirar si en tu sistema existe la funcion 'rint' (tambien 'nearbyint'),
# > o 'round' (ese forma parte del standard C99).
# >
# > Lepton.
# >
#
# Ninguna de las dos, uso el CBuilder.
# Mi duda era si existia algun tipo de declaracion para que asuma como
# redondeo por defecto el entero mas cercano, uno cree que todo lo bello
# deberia existir.

No conozco el CBuilder, pero si es un compilador ANSI C99, la
funcion round() deberia hacer lo que quieres.

Lepton.
Antoine Leca
2005-01-10 18:10:04 UTC
Permalink
Post by Eduardo
En una asignacion comun los trunca, hay funciones (ceil y floor)
para redondeos hacia arriba y hacia abajo, pero y al mas cercano?
La palabra de control del procesador matematico esta configurada
siempre para redondear al mas cercano,
Si mires al código fuente de ceil() y floor(), verrás que lo que hacen es
cambiar el modo de redondeo en la palabra de control, escribir en un int, y
devolver la palabra original...

O sea, que:
-- o bién escribes tú mismo el código de redondeo;

-- o bién pases por la reprogramación de la palabra de control, pero
¡cuidado con el multihilos!


Antoine
Eduardo
2005-01-10 18:46:23 UTC
Permalink
Post by Antoine Leca
Post by Eduardo
En una asignacion comun los trunca, hay funciones (ceil y floor)
para redondeos hacia arriba y hacia abajo, pero y al mas cercano?
La palabra de control del procesador matematico esta configurada
siempre para redondear al mas cercano,
Si mires al código fuente de ceil() y floor(), verrás que lo que hacen es
cambiar el modo de redondeo en la palabra de control, escribir en un int, y
devolver la palabra original...
-- o bién escribes tú mismo el código de redondeo;
Es lo que estoy haciendo, pero sin usar C...
int Round(float x){
int var_aux ;
asm fld x ;
asm fistp var_aux ; // al inicio se hizo _control87( RC_NEAR,MCW_RC)
;
return var_aux ;
}
Post by Antoine Leca
-- o bién pases por la reprogramación de la palabra de control, pero
¡cuidado con el multihilos!
Antoine
No me he fijado en ceil() y floor(), si en _ftol() que es la funcion que
llama cuando escribes N_int = X_float , hace precisamente lo que dices,
cambia la palabra de control (que inicialmente esta para redondear al mas
cercano!!) para truncar el numero, descarga el acumulador como entero (
FISTP var_aux) restaura la palabra de control y devuelve var_aux.
Por las dudas probe esto:
void test(void){
int N;float x=3.7;
_control87( RC_NEAR,MCW_RC) ;
N=x; // llama internamente a _ftol(float x)
............................
}

y sigue truncando el numero.

Saludos.
Eduardo.

Loading...