Wrong result of IntQ()

Everything else that doesn't fall into one of the other PB categories.
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Wrong result of IntQ()

Post 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
User avatar
STARGÅTE
Addict
Addict
Posts: 2227
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: Wrong result of IntQ()

Post 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.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Wrong result of IntQ()

Post 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
hazard
New User
New User
Posts: 7
Joined: Sat Apr 14, 2012 5:40 pm

Re: Wrong result of IntQ()

Post by hazard »

Double values do not round well at that size of integer.

Code: Select all

a.d = 922337203685477580.7      
Debug a  ;922337203685477630.0
User avatar
STARGÅTE
Addict
Addict
Posts: 2227
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: Wrong result of IntQ()

Post 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
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Wrong result of IntQ()

Post by Little John »

@Stargate:
OK, but what is then the purpose of IntQ() :?:
What do we need it for :?:

Regards, Little John
User avatar
Demivec
Addict
Addict
Posts: 4260
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Wrong result of IntQ()

Post 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.
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Wrong result of IntQ()

Post 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
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Wrong result of IntQ()

Post by wilbert »

The accuracy of a double is very well described on Wikipedia
http://en.wikipedia.org/wiki/Double-pre ... int_format
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Wrong result of IntQ()

Post 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
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

Re: Wrong result of IntQ()

Post 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.
User avatar
STARGÅTE
Addict
Addict
Posts: 2227
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: Wrong result of IntQ()

Post 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
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Wrong result of IntQ()

Post 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
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

Re: Wrong result of IntQ()

Post 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.
Post Reply