Page 2 of 2
Re: Decimal numbers problem
Posted: Fri Oct 02, 2015 1:40 pm
by SeregaZ
Debug float(53695.5 * 3.27)
will show 175584.28
but must show 175584.29 - becouse real meaning 175584.285
Re: Decimal numbers problem
Posted: Fri Oct 02, 2015 1:59 pm
by SeregaZ
i think now it count and make round correct, but it have a tonns code for this short operation... i am not like it
Code: Select all
Procedure.s NewRoundProc(tmp$)
tmp = FindString(tmp$, ".")
If tmp And Len(tmp$) - tmp > 2
cuttmp$ = Right(tmp$, Len(tmp$) - tmp - 2)
cuttmp = Val(cuttmp$)
If Len(cuttmp$) > 1
Repeat
If Val(Right(cuttmp$, 1)) > 4
cuttmp$ = StrD(cuttmp/10, 0)
Else
cuttmp$ = Left(cuttmp$, Len(cuttmp$)-1)
EndIf
cuttmp = Val(cuttmp$)
Until Len(cuttmp$) < 2
EndIf
tmp$ = Left(tmp$, tmp+2)
If Val(cuttmp$) > 4
tmp$ = ReplaceString(tmp$, ".", "")
tmp$ = Str(Val(tmp$)+1)
tmp$ = Left(tmp$, Len(tmp$)-2) + "." + Right(tmp$, 2)
EndIf
EndIf
ProcedureReturn tmp$
EndProcedure
Procedure.d countstr(tmp$)
ReplaceString(tmp$, ",", ".", #PB_String_InPlace)
tmp.d = ValD(tmp$)
ProcedureReturn tmp
EndProcedure
Procedure countstrdebug(x$, y$)
;Debug countstr(x$) * countstr(y$)
;Debug StrD(countstr(x$) * countstr(y$), 5)
;Debug StrD(countstr(x$) * countstr(y$), 4)
;Debug StrD(countstr(x$) * countstr(y$), 3)
;Debug StrD(countstr(x$) * countstr(y$), 2)
tmp$ = StrD(countstr(x$) * countstr(y$), 5)
Debug NewRoundProc(tmp$)
EndProcedure
countstrdebug("53695,5", "3,27")
countstrdebug("12067,5", "3,27")
countstrdebug("122863,5", "3,27")
countstrdebug("19675,5", "3,27")
Re: Decimal numbers problem
Posted: Fri Oct 02, 2015 2:10 pm
by RASHAD
Hi
Adapt it for your need
Code: Select all
tmp$ = "12345.124444449"
pos= FindString(tmp$,".") + 1
temp$ = Mid(tmp$,pos)
count = Len(temp$) - 2
Frac = Round(Val(temp$)/Pow(10,count),#PB_Round_Up )
Debug Left(tmp$,Len(tmp$)-Len(temp$))+Str(frac)
Re: Decimal numbers problem
Posted: Fri Oct 02, 2015 2:19 pm
by SeregaZ
thanks a lot

very short - very cute

Re: Decimal numbers problem
Posted: Fri Oct 02, 2015 2:49 pm
by SeregaZ
but... testing is show mistake

try to use tmp$ = "12345.99009"

will show 12345.100
Re: Decimal numbers problem
Posted: Fri Oct 02, 2015 3:01 pm
by GPI
Float and Doubles are always ballpark figure. The problem is, that the basis of a float/double is also 2, we calculate with 10. When you transfer one value to another basis, there are always problems. For example: 1/3 is in 10-system not solveable. with basis 3 it would be simple 0.1.
When you need a exact value, you should always calculate with Integer or quads. When you use a currency you should use cent instead of euro.
Maybe this code help (it calculates with quads instead of float with 3 digits after the point.
Code: Select all
EnableExplicit
#pointposition=3
#pointvalue=1000
Macro MUL(a,b)
(a*b/#pointvalue)
EndMacro
Macro DIV(a,b)
(a*#pointvalue/b)
EndMacro
Procedure.s Strx(a.q)
Protected ret.s
ret=Str(a)
If Len(ret)>#pointposition
ret=Left(ret,Len(ret)-#pointposition)+"."+Right(ret,#pointposition)
Else
ret="0."+RSet(ret,#pointposition,"0")
EndIf
ret=RTrim(RTrim(ret,"0"),"."); remove zero at end
ProcedureReturn ret
EndProcedure
Procedure.q ValX(str.s)
Protected ret.q
Protected a.i
a=FindString(str,".")
If a>0
ret=Val(Left(str,a-1))*#pointvalue+Val( LSet( Mid(str,a+1),#pointposition,"0"))
Else
ret=Val(str)*#pointvalue
EndIf
;Debug "VALX:"+str+" "+ret
ProcedureReturn ret
EndProcedure
Macro quote
"
EndMacro
Macro test(aa,bb)
a=valx(quote#aa#quote)
b=valx(quote#bb#quote)
Debug strx(a)+"*"+Strx(b)+"="+strx(mul(a,b))+" Double("+StrD(aa*bb)+") Float("+StrF(aa*bb)+")"
EndMacro
Define a.q,b.q
Debug strx(valx("0.001"))
Debug strx(valx("0.01"))
Debug strx(valx("0.1"))
Debug strx(valx("1"))
test (53695.5,3.27)
test(12067.5, 3.27)
test(122863.5, 3.27)
test(19675.5, 3.27)
Re: Decimal numbers problem
Posted: Fri Oct 02, 2015 3:08 pm
by SeregaZ
i will test your code later, now i think my old code will work fine:
Code: Select all
Procedure.s NewRoundProc(tmp$)
tmp = FindString(tmp$, ".")
If tmp And Len(tmp$) - tmp > 2
tmp$ = ReplaceString(tmp$, ".", "")
Repeat
forcut = Val(Right(tmp$, 1))
tmp$ = Left(tmp$, Len(tmp$)-1)
If forcut > 4
tmp$ = Str(Val(tmp$)+1)
EndIf
Until Len(tmp$) = tmp + 1
tmp$ = Left(tmp$, Len(tmp$)-2) + "." + Right(tmp$, 2)
EndIf
ProcedureReturn tmp$
EndProcedure
Debug NewRoundProc("12345.99999")
Debug NewRoundProc("12345.99009")
ops... Debug NewRoundProc("999.999") work wrong

)))
Re: Decimal numbers problem
Posted: Fri Oct 02, 2015 3:33 pm
by SeregaZ
that is finaly
Code: Select all
Procedure.s NewRoundProc(tmp$)
tmp = FindString(tmp$, ".")
tik = Len(tmp$) - tmp
If tmp And tik > 2
tmp$ = ReplaceString(tmp$, ".", "")
Repeat
forcut = Val(Right(tmp$, 1))
tmp$ = Left(tmp$, Len(tmp$)-1)
If forcut > 4
tmp$ = Str(Val(tmp$)+1)
EndIf
tik = tik - 1
Until tik = 2
tmp$ = Left(tmp$, Len(tmp$)-2) + "." + Right(tmp$, 2)
EndIf
ProcedureReturn tmp$
EndProcedure
Procedure.d countstr(tmp$)
ReplaceString(tmp$, ",", ".", #PB_String_InPlace)
tmp.d = ValD(tmp$)
ProcedureReturn tmp
EndProcedure
Procedure countstrdebug(x$, y$)
tmp$ = StrD(countstr(x$) * countstr(y$), 5)
Debug NewRoundProc(tmp$)
EndProcedure
countstrdebug("53695,5", "3,27")
countstrdebug("12067,5", "3,27")
countstrdebug("122863,5", "3,27")
countstrdebug("19675,5", "3,27")
Debug NewRoundProc("12345.99999")
Debug NewRoundProc("12345.99009")
Debug NewRoundProc("999.999")
Re: Decimal numbers problem
Posted: Fri Oct 02, 2015 3:34 pm
by SeregaZ
GPI, i think
ret=RTrim(RTrim(ret,"0"),"."); remove zero at end
from your code will be nice in my too

Re: Decimal numbers problem
Posted: Fri Oct 02, 2015 4:48 pm
by SeregaZ
this is epic fail

i am so many code make, and found - original software, for what i am build main - have wrong round function

and this is goverment software! my country is suks! it get only 3 symbol after "," and round it to 2. even 4 symbol was 9 - it is just cut. i want kill that goverment programmers

))
Re: Decimal numbers problem
Posted: Fri Oct 02, 2015 5:39 pm
by RASHAD
Code: Select all
Procedure getit(tmp$)
pos= FindString(tmp$,".")
int$ = Left(tmp$,pos-1)
frac$ = Mid(tmp$,pos+1)
frac.f = Round(Val(frac$)/Pow(10,Len(frac$)-2),#PB_Round_Nearest )
tmp.f = ValF(int$)+frac/100
Debug StrF(tmp,2)
EndProcedure
getit("12345.99999")
getit("12345.99009")
getit("999.999")
Re: Decimal numbers problem
Posted: Fri Oct 02, 2015 6:03 pm
by jack
@SeregaZ
perhaps you should consider using a decimal math library, especially if your program is dealing with money.
Re: Decimal numbers problem
Posted: Fri Oct 02, 2015 9:33 pm
by akj
In my opinion
resulting in 2.7999999999999998 rather than 2.8 is not a problem, as a properly-coded program will always specify the number of decimal places to be given in the output so that it looks neat in the GUI (or other) display.
So, instead of coding 1.4+1.4, the final version of the program is far more likely to have something like
which displays 2.8 .
Re: Decimal numbers problem
Posted: Fri Oct 02, 2015 9:47 pm
by SeregaZ
and it is with money. but my programm just make some preparing operation, just have more automated operations, more userfriendly editing. it make exel file, then this exel is loading by that goverment programm. so this goverment programm is count wrong

that is way i thought - it is my code wrong, but now i know sure - it them software is wrong

so i need to make same wrong counting in my programm too, for avoid mistakes between of them. using that my code, or even better - RASHAD's code is nice. new library it is big trial for me

and it will take more code. anyway that goverment softare have additional checking of final value, so our methods of rounding is fine. in my country it names launder dirty money

goverment pay for that software, that people stole main part of money, and pay what is left for weak cheap programmers for make this software. so finaly it is ugly, laggy, buggy piece of crap.

(( i try to make some manager, that can help to users solve most problem with this goverment's fake. now it is already big project

with many functions.
RASHAD, thanks
