Decimal numbers problem

Just starting out? Need help? Post your questions and find answers here.
SeregaZ
Enthusiast
Enthusiast
Posts: 628
Joined: Fri Feb 20, 2009 9:24 am
Location: Almaty (Kazakhstan. not Borat, but Triple G)
Contact:

Re: Decimal numbers problem

Post by SeregaZ »

Debug float(53695.5 * 3.27)
will show 175584.28
but must show 175584.29 - becouse real meaning 175584.285
SeregaZ
Enthusiast
Enthusiast
Posts: 628
Joined: Fri Feb 20, 2009 9:24 am
Location: Almaty (Kazakhstan. not Borat, but Triple G)
Contact:

Re: Decimal numbers problem

Post 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")
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4972
Joined: Sun Apr 12, 2009 6:27 am

Re: Decimal numbers problem

Post 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)
Egypt my love
SeregaZ
Enthusiast
Enthusiast
Posts: 628
Joined: Fri Feb 20, 2009 9:24 am
Location: Almaty (Kazakhstan. not Borat, but Triple G)
Contact:

Re: Decimal numbers problem

Post by SeregaZ »

thanks a lot :) very short - very cute :)
SeregaZ
Enthusiast
Enthusiast
Posts: 628
Joined: Fri Feb 20, 2009 9:24 am
Location: Almaty (Kazakhstan. not Borat, but Triple G)
Contact:

Re: Decimal numbers problem

Post by SeregaZ »

but... testing is show mistake :) try to use tmp$ = "12345.99009" :) will show 12345.100
GPI
PureBasic Expert
PureBasic Expert
Posts: 1394
Joined: Fri Apr 25, 2003 6:41 pm

Re: Decimal numbers problem

Post 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)
SeregaZ
Enthusiast
Enthusiast
Posts: 628
Joined: Fri Feb 20, 2009 9:24 am
Location: Almaty (Kazakhstan. not Borat, but Triple G)
Contact:

Re: Decimal numbers problem

Post 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 :))))
SeregaZ
Enthusiast
Enthusiast
Posts: 628
Joined: Fri Feb 20, 2009 9:24 am
Location: Almaty (Kazakhstan. not Borat, but Triple G)
Contact:

Re: Decimal numbers problem

Post 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")
SeregaZ
Enthusiast
Enthusiast
Posts: 628
Joined: Fri Feb 20, 2009 9:24 am
Location: Almaty (Kazakhstan. not Borat, but Triple G)
Contact:

Re: Decimal numbers problem

Post by SeregaZ »

GPI, i think
ret=RTrim(RTrim(ret,"0"),"."); remove zero at end
from your code will be nice in my too :)
SeregaZ
Enthusiast
Enthusiast
Posts: 628
Joined: Fri Feb 20, 2009 9:24 am
Location: Almaty (Kazakhstan. not Borat, but Triple G)
Contact:

Re: Decimal numbers problem

Post 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 :)))
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4972
Joined: Sun Apr 12, 2009 6:27 am

Re: Decimal numbers problem

Post 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")

Egypt my love
jack
Addict
Addict
Posts: 1358
Joined: Fri Apr 25, 2003 11:10 pm

Re: Decimal numbers problem

Post by jack »

@SeregaZ
perhaps you should consider using a decimal math library, especially if your program is dealing with money.
akj
Enthusiast
Enthusiast
Posts: 668
Joined: Mon Jun 09, 2003 10:08 pm
Location: Nottingham

Re: Decimal numbers problem

Post 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 .
Anthony Jordan
SeregaZ
Enthusiast
Enthusiast
Posts: 628
Joined: Fri Feb 20, 2009 9:24 am
Location: Almaty (Kazakhstan. not Borat, but Triple G)
Contact:

Re: Decimal numbers problem

Post 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 :)
Post Reply