Page 1 of 2
Decimal numbers problem
Posted: Tue Jun 02, 2015 6:53 am
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.

Re: Decimal numbers problem
Posted: Tue Jun 02, 2015 7:50 am
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.

Re: Decimal numbers problem
Posted: Tue Jun 02, 2015 9:55 am
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?

Re: Decimal numbers problem
Posted: Tue Jun 02, 2015 10:46 am
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.
Re: Decimal numbers problem
Posted: Tue Jun 02, 2015 11:09 am
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
Re: Decimal numbers problem
Posted: Tue Jun 02, 2015 11:27 am
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.
Re: Decimal numbers problem
Posted: Wed Jun 03, 2015 9:17 am
by captain_skank
Not looking to cause an argument, but PB SHOULD fix the result for you.
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
Re: Decimal numbers problem
Posted: Wed Jun 03, 2015 9:42 am
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.
Re: Decimal numbers problem
Posted: Wed Jun 03, 2015 9:51 am
by Danilo
Re: Decimal numbers problem
Posted: Wed Jun 03, 2015 9:52 am
by Dude
captain_skank wrote:Debug 1.4 + 1.4
The answer is quite clearly 2.8
Sure is!

Re: Decimal numbers problem
Posted: Fri Oct 02, 2015 11:16 am
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...
Re: Decimal numbers problem
Posted: Fri Oct 02, 2015 11:30 am
by Keya
btw SeregaZ your "," to "." StringReplace looks like the type that could use #PB_String_InPlace for a speed gain
Re: Decimal numbers problem
Posted: Fri Oct 02, 2015 11:50 am
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?
Re: Decimal numbers problem
Posted: Fri Oct 02, 2015 12:54 pm
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?
Re: Decimal numbers problem
Posted: Fri Oct 02, 2015 1:35 pm
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)