Propuesta!! Función para obtener cantidad con dos decimales sin redondear

1,260 views
Skip to first unread message

Antonio Meza

unread,
Jan 20, 2016, 9:16:17 PM1/20/16
to Comunidad de Visual Foxpro en Español
Hola a todos!!!

Tengo una cantidad por ejemplo 100.99900 y quiero usar solo 100.99 para realizar cálculos no encontré una función de VFP para ello, si alguien sabe le agradecería mucho, de momento hice una pequeña función para resolver mi problema, se puede mejorar para indicar los decimales, pero de momento sirve solo para mostrar 2 pasando la cantidad, ejemplo usando ROUND() de VFP pero redondea el valor

? round(100.99900,2)
101.00

Con la pequeña función obtengo el resultado deseado.

? _DosDecimales(100.99900)
100.99

Desde la ventana de comandos de VFP copiar y pegar el código siguiente por si quieren hacer pruebas

? _DosDecimales(100.99900)
PROCEDURE _DosDecimales
LPARAMETERS _valor as Integer
LOCAL _valor_nuevo as Integer
IF VARTYPE(_valor) <> "N"
_valor = 0
ENDIF
_valor_nuevo = INT(_valor) + val(LEFT(TRANSFORM(_valor - INT(_valor) ), 4))
RETURN _valor_nuevo
ENDPROC

NOTA: Si alguien sabe de alguna función nativa seria mejor o mejorar el código mostrado.

Saludos
Antonio Meza

narcizo norzagaray

unread,
Jan 20, 2016, 9:27:26 PM1/20/16
to publice...@googlegroups.com

Por ahí anda una función truncar creo se llama que es la que yo utilizó

Jose Antonio Blasco

unread,
Jan 21, 2016, 3:45:49 AM1/21/16
to Comunidad de Visual Foxpro en Español
Prueba esto:

?Truncar(100.999000, 2)


Function Truncar
Lparameters nValor,nDec
*
Local nResul
*
nResul=Int(nValor*(10^nDec))/(10^nDec)
*
Return nResul


Un saludo.

Jose A. Blasco
Zaragoza - España
Visual FoxPro 9 SP2

"No hay camino hacia la libertad, la libertad es el camino" - Indira Gandhi
“Nunca te olvides de sonreír, porque el día que no sonrías  será un día perdido”  -  Charles Chaplin
“Todo el mundo quiere tener un amigo, pero pocos se toman la molestia de ser uno”
- Anónimo

Fernando D. Bozzo

unread,
Jan 21, 2016, 3:47:18 AM1/21/16
to Comunidad de Visual Foxpro en Español
Hola Antonio,

Podrías usar esto:

aa = 100.99900
? INT(aa*100)/100

100.99


Saludos.-

Luis Maria Guayan

unread,
Jan 21, 2016, 8:23:41 AM1/21/16
to publice...@googlegroups.com
Está en el Blog de la Comunidad VFP

-- Truncar un número --
http://comunidadvfp.blogspot.com/2004/08/truncar-un-numero.html


Luis María Guayán
Tucumán, Argentina
_______________________________
Comunidad Visual FoxPro en Español
http://comunidadvfp.blogspot.com

El 20/01/16 a las 23:16, Antonio Meza escribió:

Antonio Meza

unread,
Jan 21, 2016, 9:37:27 AM1/21/16
to Comunidad de Visual Foxpro en Español
Gracias Maestro Fernando un código muy sencillo

Antonio Meza

unread,
Jan 21, 2016, 9:39:05 AM1/21/16
to Comunidad de Visual Foxpro en Español
Gracias Maestro LuisMa, este no lo encontré me falto buscar por la palabra "Truncar" en goglee jejeje, este sirve para devolver cualquier cantidad de decimales  indicados.

saludos
Antonio Meza

Antonio Meza

unread,
Jan 21, 2016, 9:41:58 AM1/21/16
to Comunidad de Visual Foxpro en Español
Gracias Jose es parecida a la que esta en el Blog del pueblo

saludos
Antonio Meza
Message has been deleted

Fidel Charny

unread,
Jan 21, 2016, 2:24:38 PM1/21/16
to Comunidad de Visual Foxpro en Español
Carton
No entendí. Por qué no usar Round() ?


Carton Jeston (9.0.0.7423)

unread,
Jan 21, 2016, 2:57:25 PM1/21/16
to Comunidad de Visual Foxpro en Español
No te preocupes, yo tampoco entendi el proposito al principio, asi que he eliminado mi "aportacion" para no complicar lo que ya esta claro. Gracias Fidel :-D

Carton Jeston (9.0.0.7423)

unread,
Jan 21, 2016, 3:13:26 PM1/21/16
to Comunidad de Visual Foxpro en Español
He mirado el método de Fernando y es el que tengo en mi aplicación en alguna rutina de  totalizar, aunque siguiendo su filosofía  de buenas practicas pensando en reutilizar o ampliar en el futuro, añado a mi libreria truncar, previamente renombrada a noRound() porque dudo de recordar el nombre actual.... ;-)

Antonio Meza

unread,
Jan 21, 2016, 11:07:59 PM1/21/16
to Comunidad de Visual Foxpro en Español
Maestro Fernando, su código me ha salvado!!! la función de portalfox no entiendo porque falla en una tabla DBF en algunos casos me descuenta 0.01 a la cantidad y en los demás obtengo el valor correcto, en cambio su código funciono al 100%, y de 188 registros cerca de 20 o 22  registros la función Truncar fallo me restaba 0.01 a la cantidad.

saludos
Antonio Meza



El jueves, 21 de enero de 2016, 2:47:18 (UTC-6), Fernando D. Bozzo escribió:

Jose Antonio Blasco

unread,
Jan 22, 2016, 4:19:42 AM1/22/16
to Comunidad de Visual Foxpro en Español
La función "truncar", sería similar a "Floor()" pero trabajando con decimales.

Un saludo.



Jose A. Blasco
Zaragoza - España
Visual FoxPro 9 SP2

"No hay camino hacia la libertad, la libertad es el camino" - Indira Gandhi
“Nunca te olvides de sonreír, porque el día que no sonrías  será un día perdido”  -  Charles Chaplin
“Todo el mundo quiere tener un amigo, pero pocos se toman la molestia de ser uno”
- Anónimo

Carton Jeston (9.0.0.7423)

unread,
Jan 22, 2016, 5:28:51 AM1/22/16
to Comunidad de Visual Foxpro en Español
Ese caso me ha sucedido en una ocasion por culpa de round y como no tengo datos para probar, te propongo que cambies la linea de la funcion truncar:

  RETURN ROUND(INT(tnNro * ln) / ln, tnDec)

Por esta otra:

   RETURN INT(tnNro * ln) / ln

si usas el ejemplo:

? Truncar(123.456789,2)


dará el mismo resultado 123.45 pero sin el round.

Ignoro como tienes puesto el set decimals y el entorno, pero prueba
ahora con los mismos datos a ver si da el error.

Antonio Meza

unread,
Jan 22, 2016, 10:11:16 AM1/22/16
to Comunidad de Visual Foxpro en Español
Con el ejemplo del Maestro Fernando ya lo resolví jejej

Gracias Carton!!!

Carton Jeston (9.0.0.7423)

unread,
Jan 22, 2016, 12:14:57 PM1/22/16
to Comunidad de Visual Foxpro en Español
Aunque sea Viernes, eso no esta permitido. Ya que estamos con el tema, podemos intentar clarificarlo del todo y arreglar esa función truncar de nombre difícil de recordar y actualizar la entrada del blog para evitar que este mal... ;-)

Haz la prueba o pon la lista de los datos que suma mal, tengo una curiosidad insana o mas bien un trauma por lo que me han hecho pasar a veces los jodidos decimales jajajaja

http://comunidadvfp.blogspot.com/2004/08/truncar-un-numero.html

Antonio Meza

unread,
Jan 22, 2016, 12:31:59 PM1/22/16
to Comunidad de Visual Foxpro en Español
Te paso la tabla y el código para que veas en la columna diferencia como hay un -0.01 en algunos casos que la función Truncar() quita 

abre la tabla y después ejecuta el siguiente código en la linea de comandos de vfp

SELECT nsaldo200, Truncar(nsaldo200,2) as truncar, INT(nsaldo200*100)/100 as fdb, (INT(nsaldo200*100)/100 - Truncar(nsaldo200,2)) as diferencia FROM tabla
FUNCTION
Truncar(tnNro, tnDec)
  LOCAL ln
  IF EMPTY
(tnDec)
    tnDec
= 0
  ENDIF
  ln
= 10 ^ tnDec
  RETURN ROUND
(INT(tnNro * ln) / ln, tnDec)
ENDFUNC

Saludos
Antonio Meza
TABLA.dbf

Víctor Hugo Espínola Domínguez

unread,
Jan 22, 2016, 12:47:38 PM1/22/16
to publice...@googlegroups.com
En la función Truncar cambiar:

ln = 10 ^ tnDec

por

ln = CAST(10 ^ tnDec As Integer)


Saludos,
Víctor.
Lambaré - Paraguay.

Fernando D. Bozzo

unread,
Jan 22, 2016, 1:02:14 PM1/22/16
to publice...@googlegroups.com
Muy buena observación Víctor, sospeché que el problema del decimal podía deberse al tipo de dato numérico, pero la comodidad me impidió comprobarlo ;-)

Luis Maria Guayan

unread,
Jan 22, 2016, 1:42:28 PM1/22/16
to publice...@googlegroups.com
Hola a todos, haciendo las pruebas de ambas funciones veo que el problema se manifiesta al llegar a cierto número de decimales. Probe forzando el exponente como entero, pero el problema se maniefiesta al agregar decimales al numero que se desea "truncar" en ambos métodos. Creo que el problema ya es de la precisión de VFP y no de la técnica utilizada


Ejemplo 1
*funcion Truncar()
CLEAR
ln =  10 ^ 2
? ROUND(INT(1224.6000 * ln) / ln, 2)
? ROUND(INT(1224.60000 * ln) / ln, 2)
? ROUND(INT(1224.600000 * ln) / ln, 2)
? ROUND(INT(1224.6000000 * ln) / ln, 2)
? ROUND(INT(1224.60000000 * ln) / ln, 2)
? ROUND(INT(1224.600000000 * ln) / ln, 2)


Ejemplo 2
*funcion Truncar() corregida
CLEAR
ln =  INT(10 ^ 2)
? ROUND(INT(1224.6000 * ln) / ln, 2)
? ROUND(INT(1224.60000 * ln) / ln, 2)
? ROUND(INT(1224.600000 * ln) / ln, 2)
? ROUND(INT(1224.6000000 * ln) / ln, 2)
? ROUND(INT(1224.60000000 * ln) / ln, 2)
? ROUND(INT(1224.600000000 * ln) / ln, 2)


Ejemplo 3
* funcion enviada por Fernando Bozzo
CLEAR
? INT(1224.6000*100)/100
? INT(1224.60000*100)/100
? INT(1224.600000*100)/100
? INT(1224.6000000*100)/100
? INT(1224.60000000*100)/100
? INT(1224.600000000*100)/100

Lindo debate para un viernes :-D


Luis María Guayán
Tucumán, Argentina
_______________________________
Comunidad Visual FoxPro en Español
http://comunidadvfp.blogspot.com

El 22/01/16 a las 15:02, Fernando D. Bozzo escribió:

Carton Jeston (9.0.0.7423)

unread,
Jan 22, 2016, 2:40:13 PM1/22/16
to Comunidad de Visual Foxpro en Español
Antonio, esa tabla nos la guardamos para la prueba de fuego final aunque ya este resuelto. Me interesa porque en algunas ocasiones he tenido algún expediente X con los decimales como a ti ;-)

Luis María, no se si por ser Viernes y estar cansado, pero me parece ver una extraña coincidencia.

El problema parece que se desplaza de dos en dos y de dos en dos como un numero entero FFFF ó 65535.

Y usando solo el ejemplo de truncar sin modificar puedo ilustrarlo mejor modificando el valor de set decimals to, que segun como lo tengamos alterara los resultados.

set decimals to 4
1224.59
1224.59
1224.59
1224.59
1224.59
1224.59

set decimals to 3
1224.60
1224.59
1224.59
1224.59
1224.59
1224.59

set decimals to 2
1224.60
1224.60
1224.59
1224.59
1224.59
1224.59

set decimals to 1
1224.60
1224.60
1224.60
1224.59
1224.59
1224.59

set decimals to 0
1224.60
1224.60
1224.60
1224.60
1224.59
1224.59


No se si esto ayudara, os complicara mas la vida o no tiene nada que ver, pero si aplicamos set decimals to 6, las dos rutinas van bien los cuatro primeros decimales y luego falla siempre. Posiblemente al llegar al valor FFFFFFFF haga puf.

Por aqui hablan de un bug en vfp7 sobre esto, quien dice que con vfp9 no tengamos el mismo problema... http://www.tek-tips.com/viewthread.cfm?qid=242059

Quizas el problema este ahi.

Antonio Meza

unread,
Jan 22, 2016, 2:46:06 PM1/22/16
to Comunidad de Visual Foxpro en Español
Pues corrí con suerte por la cantidad de decimales jejeje con la función del maestro Fernando,

Al final todas tienen un problema segun la cantidad de los decimales.

saludos
Antonio Meza
Reply all
Reply to author
Forward
0 new messages