Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Adding large numbers
Message
De
12/09/2013 10:17:51
 
 
Information générale
Forum:
Visual FoxPro
Catégorie:
Codage, syntaxe et commandes
Versions des environnements
Visual FoxPro:
VFP 9 SP2
OS:
Windows Server 2012
Network:
Windows 2008 Server
Database:
MS SQL Server
Application:
Desktop
Divers
Thread ID:
01582980
Message ID:
01582998
Vues:
99
This message has been marked as the solution to the initial question of the thread.
A double has a precision of 15.95 digits

Currency has 18.96

If you divide the value by 10000, then add to a currency variable, the result will be accurate for this example
CREATE CURSOR cuTest (test Y)
FOR lnNr = 1 TO 7000
	INSERT INTO cutest VALUES ($12345678901.2345)
endfor
SUM test TO lntest

86419752308641.5000   // but divided by 10000
>>>If I'm running this code, the result is incorrect, because VFP cannot handle that large numbers.
>>>What would be a workaround?
>>>
>>>CREATE CURSOR cuTest (test c(20))
>>>FOR lnNr = 1 TO 7000
>>>	INSERT INTO cutest VALUES ("123456789012345")
>>>endfor
>>>SUM VAL(test) TO lntest
>>>
>>
>>
>>CREATE CURSOR cuTest (test c(20))
>>FOR lnNr = 1 TO 7000
>>    INSERT INTO cutest VALUES ("123456789012345")
>>endfor
>>SELECT  SUM(VAL(test)) FROM cuTest
>>
>>But I'm not sure of the result is correct :-)
>
>I realized the calculation must be done using character strings instead of numbers. I found the code on Tek-Tips, which gives the correct result:
>
>CREATE CURSOR cuTest (test c(20))
>FOR lnNr = 1 TO 7000
>	INSERT INTO cutest VALUES ("123456789012345")
>ENDFOR
>
>lcNumber = '0'
>SCAN
>	lcNumber = addnumbers(cutest.test,lcnumber)
>ENDSCAN
>*
>?lcNumber
>*
>*
>*
>PROCEDURE AddNumbers
>*
>PARAMETERS m.NUMBER1,m.NUMBER2
>PRIVATE m.NUMBER1,m.NUMBER2,m.CARRY,m.RESULT,m.TEMP1,m.TEMP2,M.SUMDIGIT
>M.NUMBER1 = ALLTRIM(m.NUMBER1)
>M.NUMBER2 = ALLTRIM(m.NUMBER2)
>
>** make the two strings the same length - to make processing simpler
>IF LEN(m.NUMBER1) > LEN(m.NUMBER2)
>    M.NUMBER2 = RIGHT(SPACE(LEN(m.NUMBER1))+m.NUMBER2,LEN(m.NUMBER1))
>ELSE
>    M.NUMBER1 = RIGHT(SPACE(LEN(m.NUMBER2))+m.NUMBER1,LEN(m.NUMBER2))
>ENDIF
>
>M.CARRY = 0
>M.RESULT = ""
>FOR I = LEN(m.NUMBER2) TO 0 STEP -1
>    ** extract the relevant digits
>    M.TEMP1 = VAL(SUBSTR(m.NUMBER1,I,1))
>    M.TEMP2 = VAL(SUBSTR(m.NUMBER2,I,1))
>    ** add them - with any previous carry
>    M.SUMDIGIT = m.TEMP1 + m.TEMP2 + m.CARRY
>    ** see if they fall outside the scope (so the next carry can be assessed)
>    IF m.SUMDIGIT > 9
>        ** calculate the carry
>        M.CARRY = INT(m.SUMDIGIT/10)
>        M.SUMDIGIT = m.SUMDIGIT - (m.CARRY * 10)
>    ELSE
>        ** reset the carry if it's not relevant anymore
>        M.CARRY = 0
>    ENDIF
>    ** the the result on the left side of the existing result
>    M.RESULT = STR(m.SUMDIGIT,1,0) + m.RESULT
>    ** get the next pair of digits
>NEXT
>M.RESULT = STR(m.CARRY,1,0) + m.RESULT
>** the result will now have leading zeros (result of adding spaces together)
>DO WHILE LEFT(m.RESULT,1) = "0"
>    M.RESULT = RIGHT(m.RESULT,LEN(m.RESULT)-1)
>ENDDO
>RETURN(m.RESULT)
>*
>ENDPROC
>
Gregory
Précédent
Répondre
Fil
Voir

Click here to load this message in the networking platform