Decimal numbers problem

Just starting out? Need help? Post your questions and find answers here.
emar101
New User
New User
Posts: 3
Joined: Tue Jun 02, 2015 6:43 am

Decimal numbers problem

Post by emar101 »

Hello I'm new in using purebasic. I have this problem that everytime i get input from a string gadget and convert it to double, say the input is 12.34 it will become 12.33999999999 and so on. Is there a way to retain the input as is (12.34)? Thank you for the upcoming answers. :D
User avatar
Shield
Addict
Addict
Posts: 1021
Joined: Fri Jan 21, 2011 8:25 am
Location: 'stralia!
Contact:

Re: Decimal numbers problem

Post by Shield »

No, there is not. The only way to keep the original number is storing it as a string.
Whenever you convert to double you'll have a loss of precision due to the way floating point
numbers work. That's not a bug but is to be expected. :)
Image
Blog: Why Does It Suck? (http://whydoesitsuck.com/)
"You can disagree with me as much as you want, but during this talk, by definition, anybody who disagrees is stupid and ugly."
- Linus Torvalds
emar101
New User
New User
Posts: 3
Joined: Tue Jun 02, 2015 6:43 am

Re: Decimal numbers problem

Post by emar101 »

Thank you Shield. However, do you know a procedure or a routine that i can use in order for me to use the exact number in an operation rather than the converted number? :D
User avatar
Shield
Addict
Addict
Posts: 1021
Joined: Fri Jan 21, 2011 8:25 am
Location: 'stralia!
Contact:

Re: Decimal numbers problem

Post by Shield »

PB doesn't offer anything like this natively, but you might want to have a look at GMP:
http://www.purebasic.fr/english/viewtop ... 12&t=61315

If you'd tell us what exactly you intend to do we might be able to come up with better solutions.
Image
Blog: Why Does It Suck? (http://whydoesitsuck.com/)
"You can disagree with me as much as you want, but during this talk, by definition, anybody who disagrees is stupid and ugly."
- Linus Torvalds
infratec
Always Here
Always Here
Posts: 7658
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Decimal numbers problem

Post by infratec »

Hi,

I think you did not understand what happens:

12.34 results always in any calculation to 12.33999999.
It doesn't matter if you store it up to the calculation as string or not.
When you use it for calculation it is again 12.339999.

So it's only for your display and the user and for that you can use StrF(floatnumber, 2)

But don't think that's a bug from PB.
All other languages does the same. Maybe some of them lie to you and show already a 'rounded' value.
But latest when they calculate with it ... 12.339999

You can only use .d instead of .f which can store more exactly.

Bernd
User avatar
Josh
Addict
Addict
Posts: 1183
Joined: Sat Feb 13, 2010 3:45 pm

Re: Decimal numbers problem

Post by Josh »

If you have always two digits after decimal point, use a long/integer/quad and store the value multiplied with the factor of 100.
sorry for my bad english
User avatar
captain_skank
Enthusiast
Enthusiast
Posts: 642
Joined: Fri Oct 06, 2006 3:57 pm
Location: England

Re: Decimal numbers problem

Post by captain_skank »

Not looking to cause an argument, but PB SHOULD fix the result for you.

Code: Select all

Debug 1.4 + 1.4
results in 2.7999999999999998 which is wrong

The answer is quite clearly 2.8

How PB, the OS or the processor handle numbers internally is irrelevant as it needs to return the correct value.

Just my two cents
User avatar
Shield
Addict
Addict
Posts: 1021
Joined: Fri Jan 21, 2011 8:25 am
Location: 'stralia!
Contact:

Re: Decimal numbers problem

Post by Shield »

It's only wrong in a mathematical sense. The result is as close as you can get with floats.
It has nothing to do with PB, it has to do with the way floating point numbers are stored and handled.
The reason you get this weird number is that it's impossible to express 2.8 as a binary float.

It's not a bug, it's just how it is. Floats are designed to be fast and provide a good approximation.
There are numerous libraries designed specifically for the exact calculation of large numbers.
Image
Blog: Why Does It Suck? (http://whydoesitsuck.com/)
"You can disagree with me as much as you want, but during this talk, by definition, anybody who disagrees is stupid and ugly."
- Linus Torvalds
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: Decimal numbers problem

Post by Dude »

captain_skank wrote:Debug 1.4 + 1.4
The answer is quite clearly 2.8

Code: Select all

num.d = 1.4 + 1.4
Debug StrD(num)
Sure is! ;)
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 »

so have you any solution about it? it not want to make correct round:

Code: Select all

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)

EndProcedure

countstrdebug("53695,5", "3,27")

Debug ""

countstrdebug("12067,5", "3,27")
first time work fine, but second is suks... 39460.725 must come to 39460.73 - but it is 39460.72 hrrrrrrrrrrrrrrr...
Last edited by SeregaZ on Fri Oct 02, 2015 11:44 am, edited 1 time in total.
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Re: Decimal numbers problem

Post by Keya »

btw SeregaZ your "," to "." StringReplace looks like the type that could use #PB_String_InPlace for a speed gain
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 am obey and fix it :) but anyway need to a little help with that.

i'll need to get all digits, what lay far than 2 symbols? and check it one by one?
39460.72499 - get 499 as val, then use some like this: StrD(499/10, 0) in repite until it will get only 1 digit and check it 0-4 or 5-9?
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 »

some like this?

Code: Select all

tmp$ = "12345.124444449"
;tmp$ = "12345.12"
;tmp$ = "12345.123"

tmp = FindString(tmp$, ".")
If tmp And Len(tmp$) - tmp > 2
  
  cuttmp$ = Right(tmp$, Len(tmp$) - tmp - 2)
  cuttmp = Val(cuttmp$)
  
  Debug cuttmp
  Debug 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

  Debug cuttmp$
  
  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

Debug tmp$
maybe someone know more ellegant solution?
User avatar
Paul
PureBasic Expert
PureBasic Expert
Posts: 1285
Joined: Fri Apr 25, 2003 4:34 pm
Location: Canada
Contact:

Re: Decimal numbers problem

Post by Paul »

This procedure has served me well. I think it came from Danilo back in the day?

Code: Select all

Procedure.s Float(number.f)
  places.l=2
  vf.f=number*Pow(10,places)
  vs.s=Str(vf)
  rs.s=Left(vs,Len(vs)-places)+"."+Right(vs,places)
  If rs=".00" Or rs=".0"
    rs="0"
  EndIf
  ProcedureReturn rs
EndProcedure


Debug float(1.4+1.4)
Image Image
Post Reply