Ir al contenido


Foto

Redondeo de cantidades


  • Por favor identifícate para responder
11 respuestas en este tema

#1 JRichard

JRichard

    Advanced Member

  • Miembros
  • PipPipPip
  • 67 mensajes

Escrito 17 enero 2014 - 05:36

Hola, espero estén bien y hayan recibido un Feliz año nuevo! <:o) Tenia tiempo sin pasar por el foro jejeje! Escribo porque tengo la duda  sobre como redondear una cantidad en delphi.

En si, necesito lograr redondear una cifra y solo limitarla a que tenga 3 decimales por defecto. 

Como ejemplo me encuentro calculando un monto total, aplicando un 9% de impuesto a el monto 131.58. Entonces seria 131.58 * 0.09 lo que da como resultado 11.8422 esto lo sumo al monto (131.58) y obtendría el monto total de 143.4222, necesito que el monto total me de 143.422 o sea redondear a 3 decimales, en caso de que el monto total fuese 143.4226 entonces me quede 143.423 aplicando el redondeo.

No se si existe alguna función en delphi que pueda aplicar para solucionar este detalle o tenga que ingeniármelas de otra forma, si pueden ayudarme se lo agradecería mucho!  (y)
  • 0

#2 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3.486 mensajes
  • LocationMexico City

Escrito 17 enero 2014 - 05:42

Puedes utilizar el SimpleRoundTo (y)

Saludox ! :)
  • 0

#3 TiammatMX

TiammatMX

    Advanced Member

  • Miembros
  • PipPipPip
  • 1.750 mensajes
  • LocationUniverso Curvo\Vía Láctea\Sistema Solar\Planeta Tierra\América\México\Ciudad de México\Xochimilco\San Gregorio Atlapulco\Home

Escrito 17 enero 2014 - 05:45

...Como ejemplo me encuentro calculando un monto total, aplicando un 9% de impuesto a el monto 131.58. Entonces seria 131.58 * 0.09 lo que da como resultado 11.8422 esto lo sumo al monto (131.58) y obtendría el monto total de 143.4222, necesito que el monto total me de 143.422 o sea redondear a 3 decimales, en caso de que el monto total fuese 143.4226 entonces me quede 143.423 aplicando el redondeo...


Un par de preguntas. ¿Redondeo o truncamiento? ¿Sólo para mostrar o también lo usarás para cálculo? Para la primera pregunta, puedes usar RoundTo:

Rounds a floating-point value to a specified digit or power of ten using “Banker’s rounding”.
Unit
Math
Category
Arithmetic routines

type TRoundToRange = -37..37;
function RoundTo(const AValue: Double; const ADigit: TRoundToRange): Double;

Description

Call RoundTo to round AValue to a specified power of ten.

AValue is the value to round.

ADigit indicates the power of ten to which you want AValue rounded. It can be any value from –37 to 37 (inclusive).

RoundTo uses “Banker’s Rounding” to determine how to round values that are exactly midway between the two values that have the desired number of significant digits. This method rounds to an even number in the case that AValue is not nearer to either value.

The following examples illustrate the use of RoundTo:

Expression Value

RoundTo(1234567, 3) 1234000
RoundTo(1.234, -2) 1.23
RoundTo(1.235, -2) 1.24
RoundTo(1.245, -2) 1.24

Note: The behavior of RoundTo can be affected by the Set8087CW procedure or SetRoundMode function.


Si solamente mostrarás tu resultado, con un "picture" para tu campo o componente..., algo así como '###0.##0'
  • 0

#4 JRichard

JRichard

    Advanced Member

  • Miembros
  • PipPipPip
  • 67 mensajes

Escrito 17 enero 2014 - 05:50

Hola, gracias por responder  :) . Probare con SimpleRoundTo a ver que tal Fenareth.

TiammatMX, es redondeo y el dato que obtenga es para mostrar en una caja de texto y también lo voy a enviar a la base de datos. Por eso necesito redondear la cifra a 3 decimales porque así me lo están exigiendo para la aplicación :) 
  • 0

#5 JRichard

JRichard

    Advanced Member

  • Miembros
  • PipPipPip
  • 67 mensajes

Escrito 17 enero 2014 - 06:21

Muchas Gracias Fenareth, el SimpleRoundTo funciona a la perfección :)
  • 0

#6 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 17 enero 2014 - 09:37

Hola,
Advertencia: SimpleRoundTo siempre redondea hacia el máximo valor. Es decir al infinito. ¿Es esto realmente lo que se busca?
Hay otros métodos que son más "sencibles" a los modos de redondeo. Recomiendo que se le ponga mucha atención a las otras funciones de redondeo: RoundTo y Round.
Delphi, además, cuenta con procedimientos para establecer los modos de redondeo, como así también controlar la palabra de control.

Cuando se trata de redondeo hay que ponerle mucho ojo.

Saludos,

  • 0

#7 JRichard

JRichard

    Advanced Member

  • Miembros
  • PipPipPip
  • 67 mensajes

Escrito 18 enero 2014 - 04:49

Hola Delphius, en si lo que necesitaba era redondear cantidades a 3 decimales nada más, por ejemplo 1550,2345678 matemáticamente redondeado a 3 decimales sería 1550,235 el SimpleRoundTo me funciono ahora de acuerdo a lo que me dices no se si sería lo ideal.
  • 0

#8 genriquez

genriquez

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 539 mensajes
  • LocationCali, Colombia

Escrito 18 enero 2014 - 05:32

Jajaja, esa es la maldición del conocimiento,  todo es seguro hasta que te enteras que hay algo más allá.

Saludos
  • 0

#9 JRichard

JRichard

    Advanced Member

  • Miembros
  • PipPipPip
  • 67 mensajes

Escrito 18 enero 2014 - 06:12

jajajaja! Sí, estaba muy feliz con mi SimpleRoundTo. Pero bueno si existe un mas allá es por algo y la idea es aprender cada vez más aunque a veces se haga tedioso!  8o| jejeje!
  • 0

#10 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 20 enero 2014 - 10:54

Hola Delphius, en si lo que necesitaba era redondear cantidades a 3 decimales nada más, por ejemplo 1550,2345678 matemáticamente redondeado a 3 decimales sería 1550,235 el SimpleRoundTo me funciono ahora de acuerdo a lo que me dices no se si sería lo ideal.

Prueba ese número con los diferentes modos de redondeo por favor.
Como he dicho, el SimpleRoundTo SIEMPRE redondea al infinito. Y si se tiene en cuenta los posibles problemas que puede presentarse con números que no tienen representación binaria el resultado que puede obtenerse puede que no cuadre con el valor a esperar.
En principio SimpleRoundTo aplicaría el mal llamado método del Banquero (algo bastante raro ya que realidad los bancos no utilizan este algoritmo), o el de toda la vida en la que para el digito a precisión se le suma uno cuando el siguiente dígito es 5 o superior, o se "trunca" para 4 o inferior.
El punto está en que si se combina este algoritmo en una sucesión de operaciones matemáticas sencibles a la precisión de decimales que pueden estar afectadas al redondeo interno del procesador a la larga este método puede dar más sorpresas que alegrías.

RoundTo y Round por su parte tienen en cuenta el modo de redondeo que está activo al momento de uso por la palabra de control del procesador y pueden mitigar la pérdida de precisión ante dicha sucesión de operaciones y el redondeo interno.

Repito: debe ponerse mucho cuidado cuando se redondea y estar consciente de que se está usando el redondeo correcto en el momento correcto.
Como nota adicional: si los valores que estás obteniendo representan valores monetarios lo más habitual es que adoptes un criterio de precisión fija. Esto permite que internamente se opere con aritmética entera que es absolutamente precisa (mientras no se produzca desbordamiento).

Saludos,
  • 0

#11 genriquez

genriquez

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 539 mensajes
  • LocationCali, Colombia

Escrito 20 enero 2014 - 11:16

Hola, todas estas funciones son importantes cuando de dinero se trata o calculo de intereses o cosas similares, donde una millonésima de unidad te puede descuadrar, sin embargo para aplicaciones más sencillas un round es suficiente o un trunc si lo que quieres es desechar los decimales adicionales.

Me ha sucedido en consultas a bases de datos, especialmente a Access que los decimales no cargan igual en Delphi que en el propio lenguaje Access, así que para redondear (solo en los casos mencionados) utilizo el truco  Trunc(Valor*1000)/1000 de esa manera se obtiene el valor con dos decimales.  El Trunc se puede reemplazar por un Round según el caso y eso es todo.

Saludos.
  • 0

#12 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 20 enero 2014 - 11:50

Hola, todas estas funciones son importantes cuando de dinero se trata o calculo de intereses o cosas similares, donde una millonésima de unidad te puede descuadrar, sin embargo para aplicaciones más sencillas un round es suficiente o un trunc si lo que quieres es desechar los decimales adicionales.

Me ha sucedido en consultas a bases de datos, especialmente a Access que los decimales no cargan igual en Delphi que en el propio lenguaje Access, así que para redondear (solo en los casos mencionados) utilizo el truco  Trunc(Valor*1000)/1000 de esa manera se obtiene el valor con dos decimales.  El Trunc se puede reemplazar por un Round según el caso y eso es todo.

Saludos.

RoundTo y SimpleRoundTo tienen un algoritmo muy similar a lo que describes y entre ellos. De hecho solamente se diferencian en un único punto muy importante: RoundTo internamente aplica Round mientras que SimpleRoundTo aplica un Trunc sumado un .5  ;)

Saludos,
  • 0




IP.Board spam blocked by CleanTalk.