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

Code: Select all

Debug 1.4+1.4
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

Code: Select all

StrD(1.4 + 1.4, 1)
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 :)