Rounding of doubles!

Everything else that doesn't fall into one of the other PB categories.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Rounding of doubles!

Post 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.
I may look like a mule, but I'm not a complete ass.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Rounding of doubles!

Post by IdeasVacuum »

It is a fault, but does anyone need an accuracy beyond ten decimal places?
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Rounding of doubles!

Post 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.
I may look like a mule, but I'm not a complete ass.
jack
Addict
Addict
Posts: 1359
Joined: Fri Apr 25, 2003 11:10 pm

Re: Rounding of doubles!

Post 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.
User avatar
skywalk
Addict
Addict
Posts: 4318
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Rounding of doubles!

Post by skywalk »

Use StrD() :wink:

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)
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Rounding of doubles!

Post 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. :)
I may look like a mule, but I'm not a complete ass.
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Rounding of doubles!

Post 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
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Rounding of doubles!

Post 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.
I may look like a mule, but I'm not a complete ass.
Post Reply