Viernes 8 de Noviembre de 2024, 10:03
SoloCodigo
Bienvenido(a),
Visitante
. Por favor,
ingresa
o
regístrate
.
¿Perdiste tu
email de activación?
Inicio
Foros
Chat
Ayuda
Buscar
Ingresar
Registrarse
SoloCodigo
»
Foros
»
CLR: .Net / Mono / Boo / Otros CLR
»
VB .NET
(Moderador:
ElNapster
) »
problema con decimales
« anterior
próximo »
Imprimir
Páginas: [
1
]
Autor
Tema: problema con decimales (Leído 2788 veces)
oscuros
Nuevo Miembro
Mensajes: 5
problema con decimales
«
en:
Jueves 18 de Diciembre de 2008, 12:56 »
0
Buenas, verán tengo un programa donde en una fórmula me aparece con dos decimales, pero lo que necesito es que si el decimal está entre 0 i 0.25 que redondee hacia abajo, si el decimal está entre 0.25 i 0.75 que redondee a 0.50 y que si está por encima de 0.75 que redondee para arriba.
Alguién sabe como puedo hacer eso?
Muchas gracias
Tweet
oscuros
Nuevo Miembro
Mensajes: 5
Re: problema con decimales
«
Respuesta #1 en:
Viernes 19 de Diciembre de 2008, 10:00 »
0
Ahora que me lo miro creo q no me he explicado bien, lo d ls decimales no es para la formula sino para el resultado de ésta. Que me aparece con dos decimales y lo que quiero es q me redondee los decimales al numero entero anterior o siguiente o redondee al numero ,5.
Gracias
Nebire
Miembro HIPER activo
Mensajes: 670
Re: problema con decimales
«
Respuesta #2 en:
Martes 30 de Diciembre de 2008, 11:30 »
0
Hay que crear unas pequeñas funciones que nos den el formato que necesitemos, te pongo un ejemplo con 3 funciones (sobrecargadas) que soluciona estos problemas... y de ,los que puedes deducir el camino a seguir para ajustarlo a otras ideas.
En esta primera función, se pasa el valor que se desea formatear y se pasa el límite que fija redondearse arriba o abajo. en el código del 'botón 1' se muestra ejemplos y el resultado de llamadas con distintos valores.
Código: Visual Basic
' fijado un limite lo que supera esos decimales devuelve el siguiente entero
' si no supera el límite devuelve el entero
Public
Function
Redondear(
ByVal
cifra
As
Double
,
ByVal
Limite
As
Double
)
Dim
resto
As
Single
= cifra
Mod
1
If
resto <= Limite
Then
Return Math.Floor(cifra)
Else
Return Math.Ceiling(cifra)
End
If
End
Function
Private
Sub
Button1_Click(
ByVal
sender
As
System.
Object
,
ByVal
e
As
System.EventArgs) Handles Button1.Click
' usando 1 limite:
MsgBox(Redondear(234.54, 0.4))
' devuelve 235
MsgBox(Redondear(234.54, 0.6))
' devuelve 234
MsgBox(Redondear(234.54, 0.54))
' devuelve 234
MsgBox(Redondear(234.99, 0.98))
' devuelve 235
End
Sub
En la siguiente función, que es una sobrecarga de la anterior se pasan 2 límites, uno inferior y otro superior si el límite superior es un punto superior al limite inferior se comporta como la función anterior también sucede este comportamiento si el límite superior es igual o menor que el limite inferior, pero si el límite superior dista del limite inferior se devuelve el valor que se introdujo sin formatear...
El 'botón 2' prueba el uso de esta función con algunos ejemplos.
Código: Visual Basic
' ahora se usan 2 límites, si es menor o igual al limite inferior devuelve el entero anterior,
' si es mayor o igual que el limite superior devuelve el entero superior
' si está entre ambos límites devuelve el valor entrado.
Public
Function
Redondear(
ByVal
cifra
As
Double
,
ByVal
LimiteInf
As
Double
,
ByVal
LimiteSup
As
Double
)
Dim
resto
As
Single
= cifra
Mod
1
If
resto <= LimiteInf
Then
Return Math.Floor(cifra)
ElseIf
resto >= LimiteSup
Then
Return Math.Ceiling(cifra)
Else
Return cifra
End
If
End
Function
Private
Sub
Button2_Click(
ByVal
sender
As
System.
Object
,
ByVal
e
As
System.EventArgs) Handles Button2.Click
' usando 2 limites: superior e inferior
MsgBox(Redondear(234.54, 0.4, 0.6))
' devuelve 234.54
MsgBox(Redondear(234.54, 0.5, 0.51))
' devuelve 235
MsgBox(Redondear(234.34, 0.5, 0.51))
' devuelve 234
MsgBox(Redondear(234.34, 0.25, 0.26))
' devuelve 235
MsgBox(Redondear(234.54, 0.5, 0.2))
' devuelve 235 si limite superior es menor que limite inferior este caso es equivalente a usar 1 sólo límite.
end
sub
En la 3ª función que es sobrecarga de las anteriores se muestra justo el caso que indicas
. Esto es usamos 3 límites. Si la parte decimal es igual o menor que el limite inferior se redondea al entero menor más próximo, si la parte decimal es igual o superior al límite superior edondea al entero mayor más próximo y si no es ningúno de los casos anteriores se devuelve la parte entera + el límite medio fijado.
Nota que el límite medio no realiza comprobaciones de si está en un rango dado, esto sólo sería necesario si quisiéramos indicar 4 límites. Lo que hace es que si no es ninguno de los 2 casos anteriores.
En tu pregunta los valores para estos límites deberían ser: redondear( valor, 0.25,0.75,0.5 )
El 'botón 3' muestra unos ejemplos del uso de esta función y el resultado a cada caso.
Código: Visual Basic
' como en el caso anterior, pero ahora cuando no está en márgenes inferior o superior devuelve el punto medio indicado...
Public
Function
Redondear(
ByVal
cifra
As
Double
,
ByVal
LimiteInf
As
Double
,
ByVal
LimiteSup
As
Double
,
ByVal
LimiteMed
As
Double
)
Dim
resto
As
Single
= cifra
Mod
1
If
resto <= LimiteInf
Then
Return Math.Floor(cifra)
ElseIf
resto >= LimiteSup
Then
Return Math.Ceiling(cifra)
Else
Return Math.Floor(cifra) + LimiteMed
End
If
End
Function
Private
Sub
Button2_Click(
ByVal
sender
As
System.
Object
,
ByVal
e
As
System.EventArgs) Handles Button2.Click
' usando los 3 límites: supeior inferior y medio
MsgBox(Redondear(234.54, 0.4, 0.6, 0.5))
' devuelve 234.5
MsgBox(Redondear(234.62, 0.5, 0.6, 0.5))
' devuelve 235
MsgBox(Redondear(234.50, 0.5, 0.6, 0.3))
' devuelve 234 pero un valor de de 234.51 devolvería 234.3
MsgBox(Redondear(234.34, 0.25, 0.6, 0.3))
' devuelve 234.3
End
Sub
Math.Ceiling, Math.Floor y math.Round son funciones de redondeo, la 1ª devuelve el entero siguiente al actual, el 2ª ídem pero aplicando el inferior, el 3ª devuelve el entero más próximo, hemos usado floor y ceiling para contruir nuestro propio formato de redondeo. La traducción literal de ceiling y floor es techo y suelo, para que no parezca algo 'raro' o misterioso...
Si tienes que hacer bastantes más cosas al respecto podría interesarte realizar una pequeña clase de matematicas donde vas reuniendo este tipo de funciones.
Además las funciones no son fijas en el sentido de que en cada llamada podemos fijar unos límites distintos. si creas una clase podrías especificar unas propiedades con dichos límites (que podrían definirse con el constructor de la instancia) y así no pasar en cada llamada a la función estos valores sino que los recogería internamente... eso queda como ejercicio para tí.
Cualquier duda que tengas pregunta...
«Ma non troppo»
----> ModoVacaciones = False<----
oscuros
Nuevo Miembro
Mensajes: 5
Re: problema con decimales
«
Respuesta #3 en:
Lunes 12 de Enero de 2009, 09:59 »
0
Muchas gracias pero al final lo he hecho con otro codigo.
Private Function getRedondeo(ByVal numero As Decimal) As Decimal
Dim salida As Decimal = 0
Dim i As Integer = 0
Dim b As Integer = 0
Dim aux As String = Format(numero, "#.00")
aux = aux * 100
Dim parteDecimal As Integer = aux Mod 100
Dim a As String = numero.ToString
Try
For i = 0 To a.Length - 1
If a.Chars(i) = "," Then
b += 1
End If
If a.Chars(i) <> "," And b = 0 Then
i += 1
End If
Next
If parteDecimal <> 0 Then
a = a.Substring(0, i)
Dim parteEntera As Integer = a
Select Case parteDecimal
Case 0 To 25
parteDecimal = 0
Case 26 To 75
parteDecimal = 50
Case 76 To 99
parteDecimal = 0
parteEntera += 1
End Select
aux = parteEntera & "," & parteDecimal
salida = CType(aux, Decimal)
Return salida
Else
End If
Catch ex As Exception
End Try
End Function
Nebire
Miembro HIPER activo
Mensajes: 670
Re: problema con decimales
«
Respuesta #4 en:
Viernes 16 de Enero de 2009, 00:01 »
0
Me parece muy bien que busques una solución alternativa.
Sin embargo al caso presente le pongo 2 'peros'.
El primero es que siempre que haya que tratar un número como caracteres (tal como haces convirtiéndolo en una batriz de chars), implica una pérdida importante de eficiencia. Esto por sí sólo, es razón suficiente para descartar un algoritmo basado en esa manera, salvo que no exista un modo alternativo realmente eficaz. En el caso presente no está justificado, las funciones que te he expuesto son muy sencillas y simples. Podrías perfectamente remplazar la parte del bloque if ---then por el bloque select case, perfectamente, para casos más o menos complejos y eso sería todo. Hablando claramente formatear un número a través de caracteres es una cagada, en el 99% de los casos.
El segundo 'pero' es que los bloques try .. catch aunque son muy útiles, hay que saber cuando usarlos. Rresulta una estupidez esperar un error donde no debe haberlo, entonces algo como
Código: Visual Basic
dim
r,s,t
as
string
s=
"Ho"
: t=
"la"
try
r = s & t
messagebox.show r
catch ex
as
exception
messagebox.show ex.exception
finally
messagebox.show
" Mundo."
end
try
.... es una solemne estupidez... Hay que utilizar bloques try..catch , pero sólo cuando pueda generarse un error que no podamos controlar, porque las funciones llamadas o los parámetros utilizados queden fuera de nuestro control. Te puedo dar
una regla sobre cuando usar bloques try..catch; es como usar un guardaespaldas, pregúntate: cuando se usa un guardaespaldas ?... cuando existe una amenaza, si no la hay, sobra
el guardaespealdas, lo mismo se aplica para el try ...catch. Para ir desde la cama al baño, no necesitas un guardaespaldas, no hay amenaza.
Por último un pero menor... es el nombre de la función... getRedondeo ... No sería más sencillo llamarlo Redondear ?, getLoquesea lo que indica es que se obtiene lo que sea, dicho de otro modo, get es tomar algo 'ya almacenado' y si fuera el caso previamente calculado. Cuando algo no está almacenado, sino que debe hacerse, debe calcularse, porque es una acción, es una acción entonces en estos casos es mejor usar un verbo, así si prefieres usar terminología inglesa podrías usar 'DoRound', 'Do' hacer... o 'CalculateRound'. Si tienes que coget una cerveza de la nevera usa GetCerveza(nevera), pero si la cerveza debe elaborarse entonces usa DoCerveza(1 litro, 5kg cebaza, 200gr malta,....).. No es lo mismo ir a una pastelería y pedir una tarta GetTarta (tomar tarta), que ir a pedir el encargo de una tarta (una tarta con unas especificaciones que implica que deba reunirse los ingredientes y hacerla), en este caso lo llamaríamos DoTarta (hacer la tarta y romarla).
Son sólo indicaciones, seguirlas o no ya es cosa tuya.
«Ma non troppo»
----> ModoVacaciones = False<----
Imprimir
Páginas: [
1
]
« anterior
próximo »
SoloCodigo
»
Foros
»
CLR: .Net / Mono / Boo / Otros CLR
»
VB .NET
(Moderador:
ElNapster
) »
problema con decimales