Page 1 of 1
Rounding of doubles!
Posted: Fri Jul 06, 2012 12:04 pm
by srod
Came across this earlier which surprised me a little. I am sure it has been discussed before, but I probably missed the relevant posts.
Of course I am aware of the limitations of the floating point representation of real numbers, but I did expect the following to produce the same results.
Code: Select all
y.d = 0.333333333333333
Debug y
Debug "======="
a$ = "0.333333333333333"
x.d = ValD(a$)
Debug x
The 2 outputs differ only very slightly, but enough for me to raise an eyebrow or six!
I came across it because I coded my own version of ValD() which does a little more than PB's function. It does produce identical results to ValD() however. I've looked at the ASM generated by PB and can see that the difference is in the lower 32-bits of the 64-bit value.
Does this inconsistency equate to a bug or is it something I just have to accept?
Thanks.
Re: Rounding of doubles!
Posted: Fri Jul 06, 2012 12:14 pm
by IdeasVacuum
It is a fault, but does anyone need an accuracy beyond ten decimal places?
Re: Rounding of doubles!
Posted: Fri Jul 06, 2012 12:28 pm
by srod
If they did then they wouldn't use floating point that's for sure!
Just found it a bit odd that's all.
Re: Rounding of doubles!
Posted: Sat Jul 07, 2012 4:15 pm
by jack
the difference is probably due to the first expression being evaluated at compile time and the second evaluated at run-time, and obviously use different routines.
Re: Rounding of doubles!
Posted: Sat Jul 07, 2012 4:34 pm
by skywalk
Use StrD()
Code: Select all
Debug "-- StrD(y.d) --"
y.d = 0.333333333333333
Debug StrD(y,16)
Debug "-- StrD(a$,15digits) --"
a$ = "0.333333333333333"
x.d = ValD(a$)
Debug StrD(x,16)
Debug "-- StrD(a$,16digits) --"
b$ = "0.3333333333333333"
z.d = ValD(b$)
Debug StrD(z,16)
Re: Rounding of doubles!
Posted: Sat Jul 07, 2012 5:39 pm
by srod
Well, yes, but that is somewhat beside the point.
@Jack : yes I agree, but still, the inconsistency...
The compiler probably calls some function from the standard c lib to make the conversion or Fred coded his own c routine?
It's no big deal what with floating point being what it is anyhow. Just caught me by surprise.

Re: Rounding of doubles!
Posted: Sun Jul 08, 2012 10:02 am
by Danilo
srod wrote:The compiler probably calls some function from the standard c lib to make the conversion or Fred coded his own c routine?
sscanf and sprintf give the same result on MS Windows.
Code: Select all
ImportC "msvcrt.lib"
CompilerIf #PB_Compiler_Unicode
sscanf(*input_string,*format,*result) As "_swscanf"
sprintf(*buffer,*format,arg1.d) As "_swprintf"
CompilerElse
sscanf(*input_string,*format,*result) As "_sscanf"
sprintf(*buffer,*format,arg1.d) As "_sprintf"
CompilerEndIf
EndImport
Procedure.d ValD2(string.s)
Protected result.d
sscanf(@string,@"%lf",@result)
ProcedureReturn result
EndProcedure
Procedure.s StrD2(arg1.d)
Protected string.s = Space(100)
sprintf(@string,@"%.17lf",arg1)
ProcedureReturn string
EndProcedure
Debug ""
Debug "PureBasic"
Debug ""
y.d = 0.333333333333333
Debug y
Debug "======="
a$ = "0.333333333333333"
x.d = ValD(a$)
Debug x
Debug ""
Debug "C Runtime Library"
Debug ""
y.d = 0.333333333333333
Debug StrD2(y)
Debug "======="
x.d = ValD2(a$)
Debug x
Re: Rounding of doubles!
Posted: Sun Jul 08, 2012 10:12 am
by srod
Still comes down to the way the PB compiler interprets y.d = 0.333333333333333 though. Your ValD2() routine suggests that PB doesn't actually use a c-runtime function then to make this interpretation.