Page 1 of 1
Wrong result of IntQ()
Posted: Mon Apr 16, 2012 12:08 am
by Little John
Hi all,
the following code snipped shows wrong behaviour of IntQ() on my system (PB 4.60 on Windows XP x86). According to the PB help, the value which I'm assigning to n is the biggest allowed quad value. I always thought that it's better to use Int() or IntQ() in situations like that, but here
IntQ() returns a wrong result. Is this a bug in IntQ(), or am I overlooking something?
Code: Select all
n.q = 9223372036854775807
x.q = n/10
Debug x ; 922337203685477580 (OK)
x.q = IntQ(n/10)
Debug x ; 922337203685477632 (wrong)
Regards, Little John
Re: Wrong result of IntQ()
Posted: Mon Apr 16, 2012 1:44 am
by STARGÅTE
Int and IntQ is a function for convert a float/double to a long/quad.
In your case "n/10" will convert in a double (inaccuracy) and then convert to a quad.
So, no Bug! Incorrect use of the function.
Re: Wrong result of IntQ()
Posted: Mon Apr 16, 2012 2:55 pm
by Little John
STARGÅTE wrote:Int and IntQ is a function for convert a float/double to a long/quad.
In your case "n/10" will convert in a double (inaccuracy) and then convert to a quad.
So, no Bug! Incorrect use of the function.
Hi,
thanks for your reply.
However, what you write sounds to me like a contradiction:
Yes, Int() and IntQ() are functions for converting a float/double to a long/quad. And that's what I want to do. So why is it an incorrect use of the function? If
x.q = n/10 stores the correct value in x, and
x.q = IntQ(n/10) stores a wrong value in x, for what do we need IntQ()
Regards, Little John
Re: Wrong result of IntQ()
Posted: Mon Apr 16, 2012 3:10 pm
by hazard
Double values do not round well at that size of integer.
Code: Select all
a.d = 922337203685477580.7
Debug a ;922337203685477630.0
Re: Wrong result of IntQ()
Posted: Mon Apr 16, 2012 3:13 pm
by STARGÅTE
x.q = n/10 use integer division, full accuracy!
x.q = IntQ(n/10) were convert to:
Code: Select all
n.q = 9223372036854775807
Debug n
d.d = n/10
Debug d
x.q = IntQ(d)
Debug x
The accuracy of doubles is not enough to hold all the digits of a quad, so it comes back to this inaccuracy in last 3 digits
Re: Wrong result of IntQ()
Posted: Mon Apr 16, 2012 3:28 pm
by Little John
@Stargate:
OK, but what is then the purpose of IntQ()

What do we need it for
Regards, Little John
Re: Wrong result of IntQ()
Posted: Mon Apr 16, 2012 8:03 pm
by Demivec
Little John wrote:@Stargate:
OK, but what is then the purpose of IntQ()

What do we need it for

You need it to control whether the number is rounded or truncated.
Code: Select all
n.d = 922337203685477.50
Debug "Str: " + Str(n) ;Str: 922337203685478 ;rounded away from zero
Debug "IntQ:" + Str(IntQ(n)) ;IntQ:922337203685477 ;rounded towards zero ;truncated
Debug "Str: " + Str(-n) ;Str: -922337203685478 ;rounded away from zero
Debug "IntQ:" + Str(IntQ(-n)) ;IntQ:-922337203685477 ;rounded towards zero ;truncated
It is also needed for completeness along with Int(). Int() only produces a long, while IntQ() produces a quad.
Re: Wrong result of IntQ()
Posted: Tue Apr 17, 2012 8:14 pm
by Little John
@Demivec:
I see now, thank you!
STARGÅTE wrote:The accuracy of doubles is not enough to hold all the digits of a quad
I wasn't aware of this fact. I made some tests, and it seems that
922337203685472000 is the biggest quad number which a variable of type "double" can hold:
Code: Select all
n.q = 922337203685472000 ; OK
d.d = n
Debug n
Debug d
Debug "----------------"
n.q = 922337203685472001 ; wrong
d.d = n
Debug n
Debug d
Is this documented somewhere? If not, I think it should be done.
Regards, Little John
Re: Wrong result of IntQ()
Posted: Tue Apr 17, 2012 8:20 pm
by wilbert
The accuracy of a double is very well described on Wikipedia
http://en.wikipedia.org/wiki/Double-pre ... int_format
Re: Wrong result of IntQ()
Posted: Tue Apr 17, 2012 8:39 pm
by Little John
Thanks. IMHO it would be helpful if some basic information of this topic were contained in the PB help, namely what the smallest negative and the biggest positive quad numbers are, which a variable of type "double" can represent exactly.
Regards, Little John
Re: Wrong result of IntQ()
Posted: Tue Apr 17, 2012 10:07 pm
by Tenaja
While there isn't much about conversions, the Help file (under Variables and Types) does have the limitations of floats and doubles. The accuracy of the conversion will be no better than the accuracy of the float/double.
Special information about Floats and Doubles
A floating point number is stored in a way that makes the binary point "float" around the number, so that it is possible to store very large numbers or very small numbers. However, you cannot store very large numbers with very high accuracy (big and small numbers at the same time, so to speak).
Another limitation of floating point numbers is that they still work in binary, so they can only store numbers exactly which can be made up of multiples and divisions of 2. This is especially important to realise when you try to print a floating point number in a human readable form (or when performing operations on that float) - storing numbers like 0.5 or 0.125 is easy because they are divisions of 2. Storing numbers such as 0.11 are more difficult and may be stored as a number such as 0.10999999. You can try to display to only a limited range of digits, but do not be surprised if the number displays different from what you would expect!
This applies to floating point numbers in general, not just those in PureBasic.
Like the name says the doubles have double-precision (64 bit) compared to the single-precision of the floats (32 bit). So if you need more accurate results with floating point numbers use doubles instead of floats.
The exact range of values, which can be used with floats and doubles to get correct results from arithmetic operations, looks as follows:
Float: +- 1.175494e-38 till +- 3.402823e+38
Double: +- 2.2250738585072013e-308 till +- 1.7976931348623157e+308
More information about the 'IEEE 754' standard you can get on Wikipedia.
Re: Wrong result of IntQ()
Posted: Tue Apr 17, 2012 10:09 pm
by STARGÅTE
Doubles has a precision of
53 bits (
Double-precision floating-point format)
so, 2^53-1 = 9'007'199'254'740'991 is the last Quad which fits exactly into a double.
if the quad higher, you will lost last digit(s)
Code: Select all
Debug "accurate:"
For n=-10 To -1
Quad.q = 1<<53+n
Double.d = Quad
Debug Str(Quad)+" vs. "+StrD(Double)
Next
Debug "can be inaccurate:"
For n=0 To 10
Quad.q = 1<<53+n
Double.d = Quad
Debug Str(Quad)+" vs. "+StrD(Double)
Next
accurate:
9007199254740982 vs. 9007199254740982.0000000000
9007199254740983 vs. 9007199254740983.0000000000
9007199254740984 vs. 9007199254740984.0000000000
9007199254740985 vs. 9007199254740985.0000000000
9007199254740986 vs. 9007199254740986.0000000000
9007199254740987 vs. 9007199254740987.0000000000
9007199254740988 vs. 9007199254740988.0000000000
9007199254740989 vs. 9007199254740989.0000000000
9007199254740990 vs. 9007199254740990.0000000000
9007199254740991 vs. 9007199254740991.0000000000
can be inaccurate:
9007199254740992 vs. 9007199254740992.0000000000
9007199254740993 vs. 9007199254740992.0000000000
9007199254740994 vs. 9007199254740994.0000000000
9007199254740995 vs. 9007199254740996.0000000000
9007199254740996 vs. 9007199254740996.0000000000
9007199254740997 vs. 9007199254740996.0000000000
9007199254740998 vs. 9007199254740998.0000000000
9007199254740999 vs. 9007199254741000.0000000000
9007199254741000 vs. 9007199254741000.0000000000
9007199254741001 vs. 9007199254741000.0000000000
9007199254741002 vs. 9007199254741002.0000000000
You can not demand that the "(basic) knowledge" of floating point numbers described in the help for PureBasic.
Same with Long and Quad, will not say anything about the byte order.
Endianness
Re: Wrong result of IntQ()
Posted: Tue Apr 17, 2012 10:26 pm
by Little John
STARGÅTE wrote:You can not demand that the "(basic) knowledge" of floating point numbers described in the help for PureBasic.
... and I did not do so. I wrote
namely what the smallest negative and the biggest positive quad numbers are, which a variable of type "double" can represent exactly.
This is of practical use, so that we don't have to look into Wikipedia or any other 3rd party documentation in order to get this basic information while we are working with PB. Adding two numbers and one or two sentences to the help shouldn't be a problem.
Regards, Little John
Re: Wrong result of IntQ()
Posted: Tue Apr 17, 2012 10:39 pm
by Tenaja
Little John wrote:Adding two numbers and one or two sentences to the help shouldn't be a problem.
I agree. There is nothing more frustrating than spending hours trying to figure out why your code doesn't work just to find it is a poorly documented (or undocumented) part of PB.
On the other hand, there are more areas in the Help file that need improvement than bug reports in the forum. And I'd rather Fred ______________ than spend time on the help file.
Unfortunately, only the newbies don't fill in the blank. (Oh, yeah...and those of us who have gotten caught-up by the short help file.) Everybody else has their pet improvement they'd like to see in that line.