
Decimal numbers problem
Decimal numbers problem
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
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.
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.

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
Re: Decimal numbers problem
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
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.
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.
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
Re: Decimal numbers problem
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
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
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
- captain_skank
- Enthusiast
- Posts: 642
- Joined: Fri Oct 06, 2006 3:57 pm
- Location: England
Re: Decimal numbers problem
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
Code: Select all
Debug 1.4 + 1.4
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
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.
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.
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
Re: Decimal numbers problem
See also: Wikipedia - Floating point - Accuracy problems
- Half-precision floating-point format
- Single-precision floating-point format
- Double-precision floating-point format
- Quadruple-precision floating-point format
- Octuple-precision floating-point format
- Extended precision
- Half-precision floating-point format
- Single-precision floating-point format
- Double-precision floating-point format
- Quadruple-precision floating-point format
- Octuple-precision floating-point format
- Extended precision
Last edited by Danilo on Wed Jun 03, 2015 9:57 am, edited 1 time in total.
Re: Decimal numbers problem
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)

-
- Enthusiast
- Posts: 628
- Joined: Fri Feb 20, 2009 9:24 am
- Location: Almaty (Kazakhstan. not Borat, but Triple G)
- Contact:
Re: Decimal numbers problem
so have you any solution about it? it not want to make correct round:
first time work fine, but second is suks... 39460.725 must come to 39460.73 - but it is 39460.72 hrrrrrrrrrrrrrrr...
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")
Last edited by SeregaZ on Fri Oct 02, 2015 11:44 am, edited 1 time in total.
Re: Decimal numbers problem
btw SeregaZ your "," to "." StringReplace looks like the type that could use #PB_String_InPlace for a speed gain
-
- Enthusiast
- Posts: 628
- Joined: Fri Feb 20, 2009 9:24 am
- Location: Almaty (Kazakhstan. not Borat, but Triple G)
- Contact:
Re: Decimal numbers problem
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?

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?
-
- Enthusiast
- Posts: 628
- Joined: Fri Feb 20, 2009 9:24 am
- Location: Almaty (Kazakhstan. not Borat, but Triple G)
- Contact:
Re: Decimal numbers problem
some like this?
maybe someone know more ellegant solution?
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$
Re: Decimal numbers problem
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)