Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 13-09-2010
Avatar de Héctor Randolph
[Héctor Randolph] Héctor Randolph is offline
Miembro Premium
 
Registrado: dic 2004
Posts: 882
Poder: 20
Héctor Randolph Va por buen camino
Hola a todos

Aunque ya está resuelto, solo quiero comentar otra forma de llegar al mismo resultado. Existe la función SetRoundMode en la unidad Math.

Esto es lo que pone la ayuda:

Cita:
Description

Call SetRoundingMode to specify how the FPU handles rounding issues. The rounding mode can be any of the following values:

Value Meaning

rmNearest Rounds to the closest value.
rmDown Rounds toward negative infinity.
rmUp Rounds toward positive infinity.
rmTruncate Truncates the value, rounding positive numbers down and negative numbers up.
Entonces puedes usarla de esta forma:

Código Delphi [-]
 SetRoundMode(rmUp);
 Memo1.Lines.Clear;
 Memo1.Lines.Add(FloatToStr(RoundTo(9.975,-2)));

Saludos
Responder Con Cita
  #2  
Antiguo 13-09-2010
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.044
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Hay tantas formas de hacer una misma cosa... cada uno tiene su método/código/truco que al final llevan a la solución. Depende de la imaginación (y conocimientos) de cada uno para lograrlo
Responder Con Cita
  #3  
Antiguo 13-09-2010
Avatar de ingabraham
ingabraham ingabraham is offline
Miembro
 
Registrado: ago 2007
Posts: 614
Poder: 17
ingabraham Va por buen camino
Thumbs up

muchas gracias a todos,
sus respuestas han sido certera.
haber como finalizo este hilo
__________________
Enseñar es la virtud de un sabio.
Responder Con Cita
  #4  
Antiguo 14-09-2010
rrf rrf is offline
Miembro
 
Registrado: ago 2003
Ubicación: S/C Tenerife, España
Posts: 454
Poder: 21
rrf Va por buen camino
Wink

Hola a todos/as.

El tema del redondeo me ha preocupado en varias ocasiones.

El problema que tengo es cuando aparece un valor como 0.75444448 y lo quieres redondear a 3 decimales.

Lo normal en todas las funciones que he visto (incluidas las que he revisado en este hilo) es que, para redondear a 3 decimales, se utilizan 4 decimales y, en este ejemplo (el valor 0.75444448), el redondeo daría 0.754 .

Lo que es muy correcto, pero que no aprovecha la totalidad de decimales disponibles.

Si se aprovecharan todos los decimales para redondear, el valor final debería dar 0.755 .

Todo ello redondeando con:
Código Delphi [-]
SetRoundMode( rmUp ) ;

Como el tema no se resuelve en las funciones de otras personas que he visto, me he animado a hacer una función en la que se indique lo que es normal, el valor decimal y el número de decimales a los cuales hay que redondear; pero añadiendo otro parámetro: el número de decimales desde el que se empieza a redondear de forma decreciente.

En el ejemplo, el valor 9.97444756, se redondea a 3 decimales y se empieza a calcular el redondeo desde los 7 decimales (luego se hará con 6, luego con 5, ... hasta que se llegue a 3).

He utilizado recursión y es de la primeras veces que lo hago; así que puede haber algún error, aunque las pruebas que hice salieron bien.

Este es el código:

Código Delphi [-]
uses math ;
.......
.......

function TForm1.Redondea2(DD: double; Max_Dig, Num_Dig: integer): double;
begin
    // Redondea el valor DD
    // a un total de Num_Dig dígitos decimales
    // partiendo en el redondeo desde el dígito decimal Max_Dig
    //----------------------------------------------------------

  if Max_Dig >= Num_Dig
    then result := Redondea2( RoundTo( DD, - Max_Dig ), Max_Dig -1, Num_Dig )
    else result := DD ;

end;

procedure TForm1.btn5Click(Sender: TObject);
begin

  SetRoundMode( rmUp ) ;
  Label1.Caption := FloatToStr( Redondea2( 9.97444756, 7, 3) ) ;

end;

Lo incluyo por si esto le es útil a alguien.

Saludos.
Responder Con Cita
  #5  
Antiguo 14-09-2010
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Cita:
Empezado por rrf Ver Mensaje
Hola a todos/as.

Lo normal en todas las funciones que he visto (incluidas las que he revisado en este hilo) es que, para redondear a 3 decimales, se utilizan 4 decimales y, en este ejemplo (el valor 0.75444448), el redondeo daría 0.754 .
Efectivamente, el redondeo se aplica según el valor del dígito siguiente. Es decir que si se desea redondear el valor a 3 decimales, este último decimal se verá afectado según el valor del 4to decimal. Por ejemplo, siguiendo tu caso:

0.75444448

El 4 en negrita es el número a redondear. El 4 subrayado es el dígito a evaluar con el modo de redondeo. Dependiendo del modo se verá afectado hacia arriba, abajo, trunca, etc. Fuera del modo, todo se resume a 3 posibilidades para ese 4: Se "convierte" en 3, 4 o 5.

Así es que se aplica el redondeo. La última cifra significativa de interés al redondeo se ve afectada por la siguiente.

Cita:
Empezado por rrf Ver Mensaje
Hola a todos/as.
(...)pero que no aprovecha la totalidad de decimales disponibles.

Si se aprovecharan todos los decimales para redondear, el valor final debería dar 0.755 .
Ese criterio de redondeo no lo veo demasiado exacto y de utilidad. Es un redondeo fuera de lo normal. Me cuesta ver cómo de 0.75444448 se puede llegar a ese resultado.

Cita:
Empezado por rrf Ver Mensaje
Todo ello redondeando con:
Código Delphi [-]SetRoundMode( rmUp ) ;



Recuerda volver al modo de redondeo anterior, de otro modo todos tus cálculos se verán afectados (inflados) y el error tras unas cuantas operaciones será mayor del que te esperas.

Cita:
Empezado por rrf Ver Mensaje
Como el tema no se resuelve en las funciones de otras personas que he visto, me he animado a hacer una función en la que se indique lo que es normal, el valor decimal y el número de decimales a los cuales hay que redondear; pero añadiendo otro parámetro: el número de decimales desde el que se empieza a redondear de forma decreciente.

En el ejemplo, el valor 9.97444756, se redondea a 3 decimales y se empieza a calcular el redondeo desde los 7 decimales (luego se hará con 6, luego con 5, ... hasta que se llegue a 3).
Déjame ver si entendí... ¿Es decir empiezas a redondear cada dígito significativo hasta llegar a los decimales a considerar?

De ser así, disculpame pero creo que no es una buena idea, porque de ese modo se está incrementando el error tras cada avance. Todo comienza con un error de 0.5 ulp, después de moverse al nuevo dígito será de un máximo de 0.5 + 10, luego 0.5 + 10 + 100... y así se irá propagando hasta llegar al dígito en cuestión.
Esto en términos absolutos.

Imagínate que luego a ese resultado debes aplicar la siguiente operación:

Valor2 = Valor1 x 10000;

Hagamos de cuenta, como dices que debería ser 0.755 y no 0.745. Si hacemos dicha multiplicación se obtiene 7550 y 7450. La diferencia entre ambos es de 100, ahora multiplícalo por 100000... 75500 y 74500, diferencia: 1000.

Cuanto más sigas avanzando, más alta será la diferencia, los cálculos se harán más erróneos.

No he probado tu código. Pero si hace lo que me temo, creo que no es buen método de redondeo.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #6  
Antiguo 14-09-2010
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.044
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Estoy con Delphius, el modo propuesto por el amigo rrf está bien como ejercicio, pero no es práctico ni vale para el "mundo real", ya me imagino las caras de los clientes protestando por esos "redondeos" tan "cuadrados"

Creo que la función que he propuesto sí es válida para "la vida real":

function Redondeo (valor: Double; decimales: integer = 0): Double;

Indicas el valor a "redondear" y el número de decimales al que quieres el redondeo.
Responder Con Cita
  #7  
Antiguo 14-09-2010
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola.

Recién leo el hilo nuevamente...

Y coincido cien por ciento con Delphius.
Un error que por defecto o exceso ajustemos en diezmilésimas, podrían convertirse en centesimas, por ejemplo.

Saludos.

Última edición por ecfisa fecha: 14-09-2010 a las 18:37:09.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Como redondear un numero en un procedimiento en Firebird Gaby123 SQL 0 26-02-2007 18:25:26
Cómo Redondear a 4 decimales un campo de tipo Numérico vick Conexión con bases de datos 1 11-10-2005 01:04:23
Funcio para obtener las decimas de segundo enzo Varios 2 13-05-2005 01:06:11
Mostrar un Float como un hh:mm:ss rjsitruiz Impresión 2 04-07-2004 14:25:29


La franja horaria es GMT +2. Ahora son las 01:15:16.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi