Numero máximo de digitos en una variable para una operacion matematica en Visualfox

1,496 views
Skip to first unread message

Marito

unread,
Aug 21, 2013, 8:19:22 AM8/21/13
to publice...@googlegroups.com
VISUALFOX: es posible extender el numero máximo de: "Dígitos de precisión en cálculos numéricos" que es de 16 a mas? por ejemplo 20? Ejm. si se desea sumar a: ?44444444444444444 + 1, la respuesta correcta deberia ser:
44444444444444445, pero por ese limite de 16 digitos... solo devuelve: 44444444444444450

Ricardo Pina

unread,
Aug 21, 2013, 9:28:42 AM8/21/13
to Grupo VFP
Hola Marito
 
A veces es aplicable ser astuto como un zorro!!
Puedes aumentar el límite es esos casos cambiando la visión y en vez de hablar de unidades lo haces en millones o miles de millones.
 
Saludos


El 21 de agosto de 2013 09:19, Marito <mario...@gmail.com> escribió:
VISUALFOX: es posible extender el numero máximo de: "Dígitos de precisión en cálculos numéricos" que es de 16 a mas? por ejemplo 20? Ejm. si se desea sumar a: ?44444444444444444 + 1, la respuesta correcta deberia ser:
44444444444444445, pero por ese limite de 16 digitos... solo devuelve: 44444444444444450



--
            

                   Ricardo Pina

Desarrollo y Servicios Informáticos

                  Profesionales
               www.dsip.com.ar

 

 

Marito

unread,
Aug 21, 2013, 9:48:00 AM8/21/13
to publice...@googlegroups.com
Gracias por tu tiempo Ricardo Pina, talvez por que estoy algunos dias con esto se reducieron mis soluciones, el tma es que ese valor lo tengo almacenado en una variable x y tengo que sumarle 1 o 2 cantidades, el tema es que isualfox solo rellena con 0 "ceros"  los numeros contiguos: es decir, si redujeramos los numeros serian asi: (123456 *10) + 1 = 1234560, como notaras solo se refleja el cero y no asi el uno, ojo que reduci la cantidad de digitos solo para este ejemplo.

Fernando D. Bozzo

unread,
Aug 21, 2013, 10:03:15 AM8/21/13
to publice...@googlegroups.com
Hola Marito:

Lamentablemente eso no es posible. Para detalles más técnicos de porqué te dejo un par de links que encontré.

De la ayuda Visual FoxPro: Numeric Data Type
http://msdn.microsoft.com/en-US/library/kkeyy55s%28v=vs.80%29.aspx

Dentro de ese capítulo de la ayuda menciona a este otro artículo de la KB de Microsoft, que también referencia a Excel:
http://support.microsoft.com/kb/78113


Saludos.-

Ricardo Pina

unread,
Aug 21, 2013, 10:50:15 AM8/21/13
to Grupo VFP
Hola
 
Mi idea es engañarlo, ya que los límites son claros en ambos extremos
si vas a tomar millones tienes que hacerlo en todo momento, lo cual es tedioso y no se si es práctico para usabilidad, pero si es estrictamente necesario podría funcionar.
La cuenta sería
1234556,123456 + 0,000001 = 123456,123457
 
Saludos
 
 

Marito

unread,
Aug 21, 2013, 10:56:48 AM8/21/13
to publice...@googlegroups.com

Gracias por tu tiempo Fernando D. Bozzo

es momento de explicarte cual es la razon de mi dolor de cabeza...


y como dicen: a grandes males grandes soluciones...


actualmente tengo estas variables y en negrilla me piden obtener dos digitos de cada uno y sumanrlos todos, hasta ahi "no problem", el tema esta en que del total obtenido debo generar 5 numeros adicionales "71621",


dato1                              150312

dato2                        418917901158

dato3                          2007070201

dato4                              250031

-------------------------------------------------

                               420925371702

5 dígitos Verhoeff:            42092537170271621       -> 71621



los genero de esta manera:
(420925371702 * 10) + 7 = 4209253717027

(4209253717027 * 10 ) + 1 = 42092537170271
(42092537170271 * 10 ) + 6 = 420925371702716
(420925371702716 * 10 ) + 2 = 4209253717027162

encuentro el digito final "1" quiero adicionarlo al final de la cifra pero salta el siguiente error:

(420925371702716
2
* 10) + 1 =
42092537170271620    <- este es el error.

una de mis posibles soluciones fue capturarlo como texto ya que racionalmente deberia sumarse y listo (sin tener en cuenta la limitante del  maximo de digitos). pero...

variable =
42092537170271620
? variable
lo que obtengo es:
4.209E+16

PREGUNTA, como puedo capturar los 15 digitos sin que lo conviera a una Expresion cientifica???



El miércoles, 21 de agosto de 2013 08:19:22 UTC-4, Marito escribió:

Ricardo Pina

unread,
Aug 21, 2013, 11:06:02 AM8/21/13
to Grupo VFP
Meto la cuchara como suelen decir
 
Si ese es todo el problema y lo pueden almacenar en texto, la solución es dividirlo en dos partes, los primeros n dígitos permanecen siempre inalterables
con lo cual los puedes separar como texto, hacer las operaciones con los dígitos restantes y concatenar ambas partes como texto.
 
cnro="123456789012345"
cnro1=susbt(cnro,1,10)
nro=val(subst(11,5))
nrores=nro*10+1
cnro=susbt(cnro,1,10)+allt(str(nrores))
 
Algo así
 
Saludos
 

Marito

unread,
Aug 21, 2013, 11:23:35 AM8/21/13
to publice...@googlegroups.com

cnro="1234567890123456"
cnro1=subst(cnro,1,10)
nro=val(subst(cnro,11,6))
nrores=nro*10+1
cnro=subst(cnro,1,10)+allt(str(nrores))

? cnro
? VAL(cnro)
* lo que se obtiene es 12345678901234561 (esta perfecto), pero tomandolo como "numero"
* se convierte en:     12345678901234560

 

Ricardo Pina

unread,
Aug 21, 2013, 11:31:43 AM8/21/13
to Grupo VFP
Pues precisamente por ese tema es toda esta manipulación como texto, por el límite numérico
solo puedes tener el resultado como texto y el tratamiento numérico solo lo puedes hacer partiendo el string
 
Saludos

Fernando D. Bozzo

unread,
Aug 21, 2013, 1:22:59 PM8/21/13
to publice...@googlegroups.com
Hola Marito:

Yo creo que la idea de Ricardo es genial y te podría resolver el problema. Además hay otra cuestión, ¿con ese número final vas a hacer algo? ¿Alguna operación matemática? Porque si no es así, entonces no lo uses como número sino como un código alfanumérico.

Saludos.-


Marito

unread,
Aug 22, 2013, 10:01:35 AM8/22/13
to publice...@googlegroups.com
Pues lamentablemente si tengo que usar toda esa cifra para convertirlo en hexadecimal... mmmmmmm pero siempre hay una salida (espero...)

Carlos Miguel FARIAS

unread,
Aug 22, 2013, 1:54:36 PM8/22/13
to Grupo Fox
Probaste con datos currency? para tu caso, serviria, en lugar de sumar 1, sumas 0,001 y al mostrar lo convertis a string y luego le "perdes" la coma (punto) y c'est fini.
Un currency maneja 15 dìgitos en la parte entera y 4 decimales, total 19 dígitos

Marito

unread,
Aug 22, 2013, 3:47:51 PM8/22/13
to publice...@googlegroups.com
? 123456789012345.12345
= 123456789012345.10000

? 42092537170271.621
= 42092537170271.620

? 420925371702716.21
= 420925371702716.20

es el ultimo digito que se extravia, gracias Miguel, Fernando y Ricardo por su tiempo, pero necesito otras ideas, se me ocurrio algo asi, todo en teoria

tomar digamos los primeros 10 digitos y multiplicarlos por 10000... la cantidad de ceros para llegar a 15 digitos, eso convertirlo a hexadecimal, luego tomar el resto de la cantidad y lo propio convertirla a hexadecimal y sumar ambas cantidad, funcionara? lo pruebo cuando llegue a mi pc.


Miguel Canchas

unread,
Aug 22, 2013, 4:03:58 PM8/22/13
to publice...@googlegroups.com

a =  "42092537170271.621"

 

busco el punto(.)… y tomo las cantidades de su derecha en una variable y la de la izquierda en otra variable….luego las uno…

 

MK

Marito

unread,
Aug 22, 2013, 5:09:36 PM8/22/13
to publice...@googlegroups.com, mcan...@ximesa.com
entiendo lo que quieres decir, pero ese no es el tema, la cuestion es que Visualfox "no ve" el 1 que se encuentra al final de toda la cifra si se unen ambos lados asi como tu dices, el resultado que Visualfox maneja es: 42092537170271620

Víctor Hugo Espínola Domínguez

unread,
Aug 22, 2013, 6:54:24 PM8/22/13
to publicesvfoxpro
Hola Marito

Creo que la solución es hacer una función que manipule el número como un vector de caracteres y haga las operaciones aritméticas sobre ese vector. En el siguiente enlace se muestra las diferentes operaciones con números de diversas bases.


Saludos,
Víctor.

Carlos Miguel FARIAS

unread,
Aug 22, 2013, 6:59:50 PM8/22/13
to Grupo Fox
Estimado, dije monetario, me exprese mal.
Es monetario. O sea que adelante va el signo $
Si es cierto que
? 123456789012345.12345
= 123456789012345.10000
pero son ambos numéricos
para monetario
? $123456789012345.1234
= 123456789012345.1234
En definitiva, es cuestion de peso(s)
Saludos: Miguel, La Pampa (RA)

Ricardo Pina

unread,
Aug 22, 2013, 7:24:39 PM8/22/13
to Grupo VFP
Hola
 
Es algo tedioso pero puede funcionar.
Tendría que almacenar el numero en dos campos numéricos. ( en vez de 1 campo de 16 digitos serian 2 de 8 digitos)
Todas las operaciones tendrian que hacerse en ambas partes numericas asumiendolas como un solo número.
 
nro1[1] = 12345678
nro1[2] = 90123456
 
nro2[1] = 12345678
nro2[2] = 90123456
 
nro1[1] + nro2[1] = 24691356
nro1[2] + nro2[2] = 180246912
 
El dígito significativo de la segunda parte numérica se trunca y se suma a la primera parte numérica
nro1[1] + nro2[1] = 24691357
nro1[2] + nro2[2] = 80246912
 
Del mismo modo se haría el cambio de base a hexa y para visualizarlo sería como concatenación de ambos en formato character.
 
Saludos
 
 

Víctor Hugo Espínola Domínguez

unread,
Aug 22, 2013, 10:54:45 PM8/22/13
to publicesvfoxpro
Hola Ricardo

El problema no es de suma sino de división, porque el objetivo es convertir un número muy grande a hexadecimal y eso se logra mediante divisiones sucesivas.

Adjunto una función que recibe como parámetros un cadena de dígitos, el dividendo, y un entero, el divisor, retorna el cociente y el resto en un string. Usando esa función ya debe ser  fácil hacer la conversión de decimal a hexadecimal.

Saludos,
Víctor.

divisionstringinteger.PRG

Víctor Hugo Espínola Domínguez

unread,
Aug 23, 2013, 12:22:12 AM8/23/13
to publicesvfoxpro
Hola Marito

Adjunto las funciones para convertir a hexadecimal, la parte de la generación del número es más sencilla, la idea de Ricardo debe funcionar.

Saludos,
Víctor.

dec2hex.prg

Fernando D. Bozzo

unread,
Aug 23, 2013, 10:20:57 AM8/23/13
to publice...@googlegroups.com, mcan...@ximesa.com
Hola Marito:

Te dejo otra idea más, pero te aviso que no es rápida: Hacer tu propio programa de cálculo en Fox, pero que no tenga la limitación de Fox.
O sea, que programes la lógica aritmética que debe hacer al sumar o multiplicar los números por columnas (como nos enseñaron en el colegio) y que vayas armando tu cadena de números con tantos dígitos como haga falta.

         12345678901234567890
x                           6
   --------------------------
         xxxxxxxxxxxxxxxxx340

Luego con el resultado, podés aplicar la conversión hexadecimal correspondiente.

No sé vos, pero hacer algo así sería un reto divertido, para quienes gustan de programar, claro, y de paso se puede dejar como Open Source para que otros lo puedan usar, ya que en este caso no importa la velocidad de cálculo para hacerlo millones de veces, no? :-)

Saludos.-


Fidel Charny

unread,
Aug 23, 2013, 11:29:35 AM8/23/13
to publice...@googlegroups.com, mcan...@ximesa.com
Una versión primitiva (suma y resta) podría ser esta (+ ó - )

PROCEDURE OPERTEXT(xcVal,xcAdd,xcOper)
* LPARAMETERS xcVal,xcAdd,xcOper
* xcVal y xcAdd son alfanuméricos. xcOper: "+" ó "-"
LOCAL lcResult,lnLen,i,j,lni
xcOper=EVL(xcOper,"+")
xcOper=ALLTRIM(xcOper)
IF !INLIST(xcOper,"+","-")
MESSAGEBOX("Operación inválida")
RETURN
ENDIF
xcVal=ALLTRIM(xcVal)
xcAdd=ALLTRIM(xcAdd)

xcVal=CHRTRAN(xcVal,CHRTRAN(xcVal,"1234567890",""),"") 
xcAdd=CHRTRAN(xcAdd,CHRTRAN(xcAdd,"1234567890",""),"") 

MESSAGEBOX("xcVAl="+xcVal+CHR(13)+"xcAdd="+xcAdd)
lnLen=MAX(LEN(xcVal),LEN(xcAdd))
LOCAL ARRAY gaCalc(lnlen,3)
STORE 0 TO gaCalc


lni=0
FOR i=LEN(xcVal) TO 1 STEP -1
lni=lni+1
gaCalc[lni,1]=VAL(SUBSTR(xcVal,i,1))
NEXT

*xcAdd
lni=0
FOR i=LEN(xcAdd) TO 1 STEP -1
lni=lni+1
gaCalc[lni,2]=VAL(SUBSTR(xcAdd,i,1))
NEXT

DO case
CASE xcOper=="+"
* Operacion +
lnLleva=0
FOR i=1 TO ALEN(gaCalc,1)
gaCalc[i,3]=gaCalc[i,1]+gaCalc[i,2]+lnLleva
IF gaCalc[i,3]>9
lnLleva=INT(gaCalc[i,3]/10)
gaCalc[i,3]=gaCalc[i,3]-lnLleva*10
ELSE
lnLleva=0
ENDIF
NEXT
CASE xcOper=="-"
lnLleva=0
FOR i=1 TO ALEN(gaCalc,1)
IF gaCalc[i,2]>gaCalc[i,1]
gaCalc[i,3]=gaCalc[i,1]+10-GaCalc[i,2]+lnLleva
lnLleva=-1
ELSE
gaCalc[i,3]=GaCalc[i,1]-GaCalc[i,2]+lnLleva
lnlleva=0
ENDIF

NEXT

ENDCASE

lcResult=""
FOR i=ALEN(gaCalc,1) TO 1 STEP -1
lcResult=lcResult+LTRIM(STR(gaCalc[i,3]))
NEXT
RETURN lcResult

Víctor Hugo Espínola Domínguez

unread,
Aug 23, 2013, 1:48:02 PM8/23/13
to publicesvfoxpro
Siguiendo con la aritmética de cadenas, adjunto SumaStrigs( cadenaDig1, cadenaDig2, nBase )

Saludos,
Víctor.

SumaStrings.PRG

Fernando D. Bozzo

unread,
Aug 23, 2013, 9:54:24 PM8/23/13
to publice...@googlegroups.com, mcan...@ximesa.com
Dejo mi aporte: Una librería de clases con una clase y 2 métodos públicos: sumar() y multiplicar(), cada una acepta solo 2 parámetros de entrada. El límite teórico es de 8192 dígitos..... ¿alcanzará? :-)

Parece que algunos nos la pasamos bien ;-)

*-- ---------------------------------------------------------------------------------------------------------
*-- Autor.........................: Fernando D. Bozzo
*-- Creado el.....................: 23/08/2013 16:50
*-- Detalle.......................: LIBRERÍA DE FUNCIONES BÁSICAS DE CÁLCULO PARA CIFRAS MAYORES A 32 BITS
*-- Motivo........................: Superar la limitación de cálculo de FoxPro cuando se requiere trabajar
*--                                 con números mayores a 16 dígitos
*-- Requisitos....................: El punto decimal debe ser el internacional ==> '.'
*-- ---------------------------------------------------------------------------------------------------------

DEFINE CLASS xcalc AS CUSTOM

    HIDDEN PROCEDURE NormalizarDatosEntrada( tcDato1, tcDato2, tnMaxLen, tnLenDato1, tnLenDato2, tnMaxEnteros, tnMaxDecimales ;
            , tnPosDecimal1, tnPosDecimal2 )
        lcDato1            = ALLTRIM(tcDato1)
        lcDato2            = ALLTRIM(tcDato2)
        THIS.obtenerCaracteristicasDeLosDatos( @lcDato1, @lcDato2, @tnMaxLen, @tnLenDato1, @tnLenDato2, @tnMaxEnteros ;
            , @tnMaxDecimales, @tnPosDecimal1, @tnPosDecimal2 )
        tcDato1            = PADL( LEFT(lcDato1, tnPosDecimal1-1), tnMaxEnteros, '0' ) + '.' ;
            + PADR( SUBSTR(lcDato1, tnPosDecimal1+1), tnMaxDecimales, '0' )
        tcDato2            = PADL( LEFT(lcDato2, tnPosDecimal2-1), tnMaxEnteros, '0' ) + '.' ;
            + PADR( SUBSTR(lcDato2, tnPosDecimal2+1), tnMaxDecimales, '0' )
    ENDPROC


    HIDDEN PROCEDURE obtenerCaracteristicasDeLosDatos( tcDato1, tcDato2, tnMaxLen, tnLenDato1, tnLenDato2, tnMaxEnteros, tnMaxDecimales ;
            , tnPosDecimal1, tnPosDecimal2 )
        *-- Esta normalización se hace para acomodar las cifras y hacer que coincida
        *-- la columna del punto decimal.
        LOCAL lnSubtotalColumna, lcSubtotal, lcSubtotalColumna, lnMeLlevo, lcDato1, lcDato2, lcDigito1 ;
            , lnDigito1, lnDigito2, lnLenSubtotalColumna
        STORE 0 TO lnMeLlevo, tnMaxLen, lnDigito1, lnDigito2 ;
            , tnMaxEnteros, tnMaxDecimales, tnPosDecimal1, tnPosDecimal2, tnLenDato1, tnLenDato2
        STORE '' TO lcSubtotal, lcDato1, lcDato2
        lcDato1            = ALLTRIM(tcDato1)
        lcDato2            = ALLTRIM(tcDato2)
        tnLenDato1        = LEN(lcDato1)
        tnLenDato2        = LEN(lcDato2)
        tnPosDecimal1    = AT('.', lcDato1)
        tnPosDecimal2    = AT('.', lcDato2)

        IF tnPosDecimal1 = 0
            tnPosDecimal1 = tnLenDato1 + 1
        ENDIF

        IF tnPosDecimal2 = 0
            tnPosDecimal2 = tnLenDato2 + 1
        ENDIF

        tnMaxEnteros    = MAX( tnPosDecimal1, tnPosDecimal2 ) - 1
        tnMaxDecimales    = MAX( tnLenDato1 - tnPosDecimal1, tnLenDato2 - tnPosDecimal2, 0 )
        tnMaxLen        = tnMaxEnteros + 1 + tnMaxDecimales

        RETURN
    ENDPROC
   
   
    HIDDEN PROCEDURE calcular_MeLlevo( tcSubtotal, tnSubtotalColumna, tnMeLlevo )
        LOCAL lcSubtotalColumna, lnLenSubtotalColumna
        *-- Si es mayor a 9, separo las unidades y "me llevo" lo demás
        IF tnSubtotalColumna > 9
            lcSubtotalColumna        = TRANSFORM( tnSubtotalColumna )
            lnLenSubtotalColumna    = LEN( lcSubtotalColumna )
            tnMeLlevo                = INT( VAL( LEFT( lcSubtotalColumna, lnLenSubtotalColumna - 1 ) ) )
            tcSubtotal                = RIGHT( lcSubtotalColumna, 1 ) + tcSubtotal
        ELSE    && Es <= 9: Tomo las unidades
            tnMeLlevo                = 0
            tcSubtotal                = TRANSFORM( tnSubtotalColumna ) + tcSubtotal
        ENDIF
    ENDPROC
   
   
    HIDDEN PROCEDURE normalizarDatosSalida( tcTotal )
        *-- Se quitan los ceros sobrantes
        LOCAL lnPosSignificativa, lnPosDecimal, lnLenTotal, llEncontrado

        *-- Normalizo el punto decimal
        IF RIGHT(tcTotal,1) = '.'
            tcTotal    = LEFT( tcTotal, LEN(tcTotal)-1 )
        ENDIF
       
        THIS.obtenerLenTotalYPosDecimal( tcTotal, @lnLenTotal, @lnPosDecimal )
       
        *-- Analizo los enteros
        llEncontrado    = .F.
        FOR lnPosSignificativa = 1 TO lnPosDecimal - 1
            IF SUBSTR( tcTotal, lnPosSignificativa, 1 ) # '0'
                llEncontrado    = .T.
                EXIT
            ENDIF
        ENDFOR
       
        IF llEncontrado AND lnPosSignificativa > 1
            tcTotal            = SUBSTR( tcTotal, lnPosSignificativa )
            THIS.obtenerLenTotalYPosDecimal( tcTotal, @lnLenTotal, @lnPosDecimal )
        ENDIF
       
        *-- Analizo los decimales
        IF lnPosDecimal < lnLenTotal
            llEncontrado    = .F.
            FOR lnPosSignificativa = lnLenTotal TO lnPosDecimal STEP -1
                IF SUBSTR( tcTotal, lnPosSignificativa, 1 ) # '0'
                    llEncontrado    = .T.
                    EXIT
                ENDIF
            ENDFOR
       
            IF llEncontrado AND lnPosSignificativa > 1
                tcTotal = LEFT( tcTotal, lnPosSignificativa )
            ENDIF
        ENDIF
       
    ENDPROC
   
   
    HIDDEN PROCEDURE obtenerLenTotalYPosDecimal( tcTotal, tnLenTotal, tnPosDecimal )
        tnLenTotal        = LEN( tcTotal )
        tnPosDecimal    = AT( '.', tcTotal )

        IF tnPosDecimal = 0
            tnPosDecimal    = tnLenTotal + 1
        ENDIF
    ENDPROC


    FUNCTION sumar( tcDato1, tcDato2 )
        *--
        LOCAL lnSubtotalColumna, lcSubtotal, lcSubtotalColumna, lnMeLlevo, lcDato1, lcDato2, lcDigito1 ;
            , lnMaxLen, lnDigito1, lnDigito2, lnLenSubtotalColumna
        STORE 0 TO lnMeLlevo, lnMaxLen, lnDigito1, lnDigito2, lnSubtotalColumna, lnLenSubtotalColumna
        STORE '' TO lcSubtotalColumna, lcSubtotal, lcDato1, lcDato2
        lcDato1            = ALLTRIM(tcDato1)
        lcDato2            = ALLTRIM(tcDato2)

        THIS.NormalizarDatosEntrada( @lcDato1, @lcDato2, @lnMaxLen )

        *-- Voy sumando los dígitos desde la última columna hacia la izquierda, por cada columna
        FOR I = lnMaxLen TO 1 STEP -1
            lcDigito1            = SUBSTR( lcDato1, I, 1 )

            IF lcDigito1 = '.'
                *-- Bajo el punto decimal
                lcSubtotal            = '.' + lcSubtotal
            ELSE
                lnDigito1            = INT( VAL( lcDigito1 ) )
                lnDigito2            = INT( VAL( SUBSTR( lcDato2, I, 1 ) ) )
                lnSubtotalColumna    = lnDigito1 + lnDigito2 + lnMeLlevo    && Sumo la columna y sumo el "me llevo"
                THIS.calcular_MeLlevo( @lcSubtotal, @lnSubtotalColumna, @lnMeLlevo )
            ENDIF

        ENDFOR

        THIS.normalizarDatosSalida( @lcSubtotal )

        RETURN lcSubtotal
    ENDFUNC


    FUNCTION multiplicar( tcDato1, tcDato2 )
        *--
        LOCAL lnSubtotalColumna, lcSubtotal, lcSubtotalColumna, lnMeLlevo, lcDato1, lcDato2, lcDigito1, lcDigito2, lnLenTotal ;
            , lnMaxLen, lnDigito1, lnDigito2, lnLenSubtotalColumna, lnFilaSubtotal, lnPosDecimal ;
            , lnLenDato1, lnLenDato2, lnMaxEnteros, lnMaxDecimales, lcTotal, lnPosDecimal1, lnPosDecimal2, lnMoverComaAIzq
        STORE 0 TO lnMeLlevo, lnMaxLen, lnDigito1, lnDigito2, lnSubtotalColumna, lnLenSubtotalColumna, lnPosDecimal ;
            , lnFilaSubtotal, lnLenDato1, lnLenDato2, lnMaxEnteros, lnMaxDecimales, lnPosDecimal1, lnPosDecimal2, lnLenTotal
        STORE '' TO lcSubtotalColumna, lcSubtotal, lcDato1, lcDato2, lcTotal
        lcDato1            = ALLTRIM(tcDato1)
        lcDato2            = ALLTRIM(tcDato2)

        THIS.obtenerCaracteristicasDeLosDatos( @lcDato1, @lcDato2, @lnMaxLen, @lnLenDato1, @lnLenDato2, @lnMaxEnteros, @lnMaxDecimales ;
            , @lnPosDecimal1, @lnPosDecimal2 )

        *-- Voy multiplicando los dígitos desde la última columna hacia la izquierda, por cada columna
        FOR X = lnLenDato2 TO 1 STEP -1
            lnMeLlevo        = 0
            lcSubtotal        = ''
            lcDigito2        = SUBSTR( lcDato2, X, 1 )

            IF lcDigito2 # '.'
                lnFilaSubtotal    = lnFilaSubtotal + 1

                IF lcDigito2 # '0'
                    FOR I = lnLenDato1 TO 1 STEP -1
                        lcDigito1        = SUBSTR( lcDato1, I, 1 )

                        IF lcDigito1 = '.'
                            *-- Salteo el punto decimal
                        ELSE
                            lnDigito1            = INT( VAL( lcDigito1 ) )
                            lnDigito2            = INT( VAL( lcDigito2 ) )
                            lnSubtotalColumna    = lnDigito1 * lnDigito2 + lnMeLlevo    && Multiplico la columna y sumo el "me llevo"
                            THIS.calcular_MeLlevo( @lcSubtotal, @lnSubtotalColumna, @lnMeLlevo )
                        ENDIF
                    ENDFOR

                    lcTotal    = THIS.sumar( lcTotal, lcSubtotal + REPLICATE( '0', lnFilaSubtotal - 1 ) )
                ENDIF
            ENDIF
        ENDFOR

        lnMoverComaAIzq    = lnLenDato1 - lnPosDecimal1 + lnLenDato2 - lnPosDecimal2

        lnLenTotal        = LEN( lcTotal )
        lnPosDecimal    = AT( '.', lcTotal )

        IF lnPosDecimal = 0
            lcTotal    = LEFT( lcTotal, lnLenTotal - lnMoverComaAIzq ) + '.' + SUBSTR( lcTotal, lnLenTotal - lnMoverComaAIzq + 1 )
        ELSE
            lnPosDecimal    = lnPosDecimal - lnMoverComaAIzq
            lcTotal    = CHRTRAN( lcTotal, '.', '' )
            lcTotal    = LEFT( lcTotal, lnPosDecimal - 1 ) + '.' + SUBSTR( lcTotal, lnPosDecimal + 1 )
        ENDIF

        THIS.normalizarDatosSalida( @lcTotal )

        RETURN lcTotal
    ENDFUNC


ENDDEFINE

Fernando D. Bozzo

unread,
Aug 30, 2013, 7:46:29 AM8/30/13
to publice...@googlegroups.com
Marito, ¡desapareciste! ¿Al final que pasó con esto? ¿Lo solucionaste de otra forma? ¿Te sirvió alguna de todas las soluciones que te dimos?

Fidel Charny

unread,
Aug 30, 2013, 8:00:53 AM8/30/13
to publice...@googlegroups.com
Ja, había publicado una versión mejorada de operaciones con alfanuméricos, pero se desapareció. O habré soñado. Bueno, nos divertimos un poco. También había una aclaración sobre cómo utilizar la clase de Fernando Bozzo y ahora no la veo más. Ni está borrada. 
Dicho sea de paso, mirando este trabajo de Fernando mejoré mi clase con el tema de los decimales y algún error conceptual y ahora suma, resta, multiplica y divide y encima parece que bien. O sea: Muchas gracias Fernando!!
- Y Marito?
- Mutis por el Foro.

Fernando D. Bozzo

unread,
Aug 30, 2013, 8:23:00 AM8/30/13
to publice...@googlegroups.com
ja ja ja, que bueno Fidel, al menos me alegra de que te haya servido algo de lo que hice ese día. :-)

Fernando D. Bozzo

unread,
Aug 30, 2013, 8:24:05 AM8/30/13
to publice...@googlegroups.com
Ah, sobre lo del ejemplo, lo puse como respuesta pero en otro hilo haciendo referencia a este, así que no lo soñaste ni se borró :-)




El viernes, 30 de agosto de 2013 14:00:53 UTC+2, Fidel Charny escribió:

edgar suarez kummers

unread,
Aug 30, 2013, 8:23:52 AM8/30/13
to publice...@googlegroups.com
Para operaciones entre nùmeros largos

El archivo .PIZ renombrarlo en simbolo de sistema .ZIP
El archivo .xex renombrarlo en simbolo de sistema .exe

Saludos

Please look my LINKS --- What I offer ---








edgar suarez kummers
ingeniero electrónico
matrícula 11714
diseño de software y ensamble de cuadros de control
celular Movistar Colombia: 3176992038
celular Virgin Mobile Colombia 3192316575
telèfono fijo Bogotá: 3126100


Karatsuba.piz
BigNumberCalculator1.0.xex

Mario Sirpa

unread,
Aug 30, 2013, 1:37:28 PM8/30/13
to publice...@googlegroups.com
Aqui estoy, disculpas por no responder y agradecer sus aportes, que por cierto fueron de mucha ayuda y me sirvio para aclarar muchas cosas al margen de mi actual situación. sogo en el intento de resolverlo. aun lo lo resuelvo,, pero estoy en eso, no me rendire (jejejeje), Ahora si. muchas gracias por sus aportes a todos los que siguen este hilo
--
Mario Sirpa
Telf. Cel. 705-79760

Fernando D. Bozzo

unread,
Aug 30, 2013, 2:00:30 PM8/30/13
to publice...@googlegroups.com
¡Marito! ¡Volviste! Alguna de las soluciones te tiene que servir, ¿tu problema no era la cantidad de dígitos? ¡Eso ya se resolvió! ¿Que queda?
Message has been deleted

ceau

unread,
Apr 10, 2015, 8:06:23 PM4/10/15
to publice...@googlegroups.com, mcan...@ximesa.com
Fernado cordial saludo.

En cuanto a las clases publicadas hice lo siguiente:
clea
oContr = CREATEOBJECT( "xcalc" )
n1='981989898'
n2='365464646999898'
?oContr.sumar(n1,n2)
?oContr.multiplicar(n1,n2)
?
y los resultados obtenidos solo coincidieron para la suma, pero para la multiplicacion no, en comparación con los obtenidos por la calculadora cientifica de windows, que pasaría?
Adjunto imagen.

Gracias por tu atención y que pena la tardanza...

Atte.: CESS
img1-001.png

Fernando D. Bozzo

unread,
Apr 11, 2015, 2:43:31 PM4/11/15
to publice...@googlegroups.com
Hola CESS, gracias por avisar.

Adjunto clase corregida.

Saludos.-


calc.prg

ceau

unread,
May 12, 2015, 11:18:48 AM5/12/15
to publice...@googlegroups.com, fdb...@gmail.com
Hola Fernando, cordial saludo.

He leído que hay una clase que hace las 4 operaciones básicas, según Fidel, donde se encuentra?
Fernando, otra sugerencia y/o inquietud, talvez no sería mejor aprovechar motores como MariaDB (Mysql) para resolver estas operaciones aritméticas y muchas otras como: seno, coseno, raiz cuadrada, potencia, etc. teniendo en cuenta que, por ej. MariaDB es gpl y fácil de instalar, incluso sin permisos de administrador, solo bastaría hacer la conexión ODBC, enviar los operadores y traer los resultados. O que inconveniente desde tu perspectiva podría existir? talvez porque los números son muy grandes? o las operaciones muy complejas?

Por último, y saliéndome un poco del tema, porque se pueden presentar en ocasiones problemas creando la conexión VFP - Oracle? He logrado conectar sin muchos inconvenientes VFP con SqlServer, MariaDb y Postgres, pero con Oracle se me ha dificultado, será necesario directamente atacar las librerías dll de Oracle o crear una conexion mediante la interfaz administrativa ODBC de windows? Por favor me podrías colaborar con algunos ejemplos prácticos, y si es posible con las 2 opciones: DLL y ODBC.

Seguiré testeando esta clase que me parece muy interesante.

Muchas gracias por tu atención y tus aportes.

Atte.: CESS

Fernando D. Bozzo

unread,
May 12, 2015, 1:04:50 PM5/12/15
to publice...@googlegroups.com
Hola César:


El 12 de mayo de 2015, 17:18, ceau <cea...@gmail.com> escribió:
Hola Fernando, cordial saludo.

He leído que hay una clase que hace las 4 operaciones básicas, según Fidel, donde se encuentra?

Ni idea. Hace poco yo subí una actualización a una que suma y multiplica, y que permite hasta 8192 dígitos en teoría.
El uso real era para alguien que requería trabajar con más dígitos de lo que permite Fox, y que iba a hacer pocos cálculos, así que el factor velocidad no era determinante.

 
Fernando, otra sugerencia y/o inquietud, talvez no sería mejor aprovechar motores como MariaDB (Mysql) para resolver estas operaciones aritméticas y muchas otras como: seno, coseno, raiz cuadrada, potencia, etc. teniendo en cuenta que, por ej. MariaDB es gpl y fácil de instalar, incluso sin permisos de administrador, solo bastaría hacer la conexión ODBC, enviar los operadores y traer los resultados. O que inconveniente desde tu perspectiva podría existir? talvez porque los números son muy grandes? o las operaciones muy complejas?

¿Conectarse a una BDD solamente para hacer cálculos? No me parece, es demasiado.... salvo que toda la lógica de negocio la muevas ahi, si no, no tiene sentido.

 

Por último, y saliéndome un poco del tema, porque se pueden presentar en ocasiones problemas creando la conexión VFP - Oracle? He logrado conectar sin muchos inconvenientes VFP con SqlServer, MariaDb y Postgres, pero con Oracle se me ha dificultado, será necesario directamente atacar las librerías dll de Oracle o crear una conexion mediante la interfaz administrativa ODBC de windows? Por favor me podrías colaborar con algunos ejemplos prácticos, y si es posible con las 2 opciones: DLL y ODBC.

Realmente no puedo ponerme a preparar ejemplos, porque no tengo un Oracle instalado, pero te recomendaría mirar la página de conexiones de todo tipo (http://www.connectionstrings.com/) donde vas a encontrar formas de conectarte por ADO u ODBC. En el trabajo sí tengo Oracle, y no tengo ningún problema de conexión. Lo que pasa es que tenés que tener bien configurado el Listener, el TNSNAMES.ORA, etc
Reply all
Reply to author
Forward
0 new messages