divisible by 2

If you have questions about any aspect of QBasic programming, or would like to help fellow programmers solve their problems, check out this board!

Moderators: Pete, Mods

User avatar
qbasicfreak
Veteran
Posts: 90
Joined: Wed Oct 22, 2008 3:27 pm
Location: canada

divisible by 2

Post by qbasicfreak » Sun Dec 14, 2008 6:23 pm

This is really a dumb question but how can you check if a number is a multiple of 2? I've tried everything I could think of.

ie.
IF string% = 'divisible by 2' THEN

Thanks
Qbasicfreak

Ralph
Veteran
Posts: 148
Joined: Fri Feb 09, 2007 3:10 pm
Location: Katy, Texas

Post by Ralph » Sun Dec 14, 2008 6:48 pm

Try:

IF number/2 = INT(number/2) THEN

While a number may APPEAR to be difisible by two, it may have a very small error, and not be truly an even number. For example, it we test the result of 10 ^2 against 100, we get a remainder, thus, the second line below returns, "NOT AN EVEN NUMBER", since the number has a very small remainder that is not even

PRINT 10 ^ 2 - 100 'gives a remanider, so:
IF 10 ^ 2 / 2 = 50 THEN PRINT "OK" ELSE PRINT "NOT AN EVEN NUMBER"
Ralph, with QuickBASIC 4.5, operating under Windows XP, wiht anHP LaserJet 4L Printer. Bilingual in English/Spanish

User avatar
burger2227
Veteran
Posts: 2344
Joined: Mon Aug 21, 2006 12:40 am
Location: Pittsburgh, PA

USE MOD

Post by burger2227 » Sun Dec 14, 2008 7:52 pm

MOD is Integer Remainder Division. When a whole number is odd, the remainder will be 1.

Code: Select all

 IF number MOD 2 = 0 THEN PRINT "Even" ELSE PRINT "odd"
Don't use that normal division verses Integer division stuff! Too cryptic.

As to exponents, just use a Single variable for the calculation. In QB, all numbers are single as default. You can define them otherwise using %, & or #.

variable = 10 ^ 2 ' undefined single variable

Then substitute that value to get rid of the small accuracy problems with Double values.

Ted
Please acknowledge and thank members who answer your questions!
QB64 is a FREE QBasic compiler for WIN, MAC(OSX) and LINUX : https://www.qb64.org/forum/index.php
Get my Q-Basics demonstrator: https://www.dropbox.com/s/fdmgp91d6h8ps ... s.zip?dl=0

User avatar
qbasicfreak
Veteran
Posts: 90
Joined: Wed Oct 22, 2008 3:27 pm
Location: canada

Post by qbasicfreak » Mon Dec 15, 2008 5:24 am

Thanks,
qbasicfreak

Ralph
Veteran
Posts: 148
Joined: Fri Feb 09, 2007 3:10 pm
Location: Katy, Texas

Post by Ralph » Mon Dec 15, 2008 11:04 am

That was good, Tec. I didn't understand your last part, the one about
variable = 10 ^ 2 ' undefined single variable

Then substitute that value to get rid of the small accuracy problems with Double values.
I entered"

Code: Select all

PRINT 10 ^ 2 - 100
and I got the remainder,
-6.928894E-18
indicating that 10 ^ 2 does not produce the exact value of 100 in QuickBASIC 4.5.

Running this code:

Code: Select all

FOR I = 1 TO 20
   PRINT I; I ^ 2 - I * I
NEXT I
RETURNS 0 FOR I = 1, 2, 3, 4, 6, 8, 12, and 16 only; all others give remainders. The numbers 1 through 20 either are treated as integers and the function is exact only in a few cases, or the numbers are single precision and the function returns the exact same value as the single numbers in a few cases. Sstrange. Is there an acceptable general answer that covers this?
Ralph, with QuickBASIC 4.5, operating under Windows XP, wiht anHP LaserJet 4L Printer. Bilingual in English/Spanish

User avatar
burger2227
Veteran
Posts: 2344
Joined: Mon Aug 21, 2006 12:40 am
Location: Pittsburgh, PA

Post by burger2227 » Mon Dec 15, 2008 1:20 pm

PRINT will display the correct single value for any exponent calculation. To do that, just:

PRINT 5 ^ 2 'will display Single answer of 25

All you need to do is assign the exponent calculation to Single when doing calculations:

Code: Select all

FOR I = 1 TO 20 
   value! = I ^ 2     'get rid of small double inaccuracy
   PRINT I; value! - I * I 
NEXT I
If you are using DEFINT A-Z then you must assign the Single variable type with DIM or !

QB4.5 also has speed issues with complex Double calculations. There is a fix for it called FFIX. It is not necessary for your code however.

Ted
Please acknowledge and thank members who answer your questions!
QB64 is a FREE QBasic compiler for WIN, MAC(OSX) and LINUX : https://www.qb64.org/forum/index.php
Get my Q-Basics demonstrator: https://www.dropbox.com/s/fdmgp91d6h8ps ... s.zip?dl=0

Ralph
Veteran
Posts: 148
Joined: Fri Feb 09, 2007 3:10 pm
Location: Katy, Texas

Post by Ralph » Mon Dec 15, 2008 9:45 pm

In the following code, I didn't actually use the ! to assign the single values, just the second line, "A = I ^ 2", and QB acts the same as in your example, but "I ^ 2" doesen't. Why? Is it that the default for any variable is single prexision, so that "A = number" will automatically make "number" a single precision number?

Code: Select all

FOR I = 1 TO 20
  A = I ^ 2
  PRINT I; A - 25; I ^ 2 - 25
NEXT I
Ralph, with QuickBASIC 4.5, operating under Windows XP, wiht anHP LaserJet 4L Printer. Bilingual in English/Spanish

User avatar
burger2227
Veteran
Posts: 2344
Joined: Mon Aug 21, 2006 12:40 am
Location: Pittsburgh, PA

Post by burger2227 » Mon Dec 15, 2008 11:11 pm

When you are not using a DEF statement, all undefined variables default to Single values. That strips off any Double inaccuracies!

You are probably used to thinking that they are Integers. Single variables do not have the decimal point inaccuracies that Double values do. So Integer values are preserved in Single values.

Doubles can change the value 11 to 11.0000000001. That causes problems sometimes.

Ted
Please acknowledge and thank members who answer your questions!
QB64 is a FREE QBasic compiler for WIN, MAC(OSX) and LINUX : https://www.qb64.org/forum/index.php
Get my Q-Basics demonstrator: https://www.dropbox.com/s/fdmgp91d6h8ps ... s.zip?dl=0

Ralph
Veteran
Posts: 148
Joined: Fri Feb 09, 2007 3:10 pm
Location: Katy, Texas

Post by Ralph » Tue Dec 16, 2008 11:00 pm

Ted, we're still not there. In the code, "FOR I = 1 TO 20", doesen't the vaiable I qualify for single precision assignment? If so, why does the example code in my previous post not give A 0 for "PRINT I ^ 2 - I* I" for all valuies of I? It does, but only for values of I of 1, 2, 3, 4, 6, 8, 12, and 16.
Ralph, with QuickBASIC 4.5, operating under Windows XP, wiht anHP LaserJet 4L Printer. Bilingual in English/Spanish

User avatar
burger2227
Veteran
Posts: 2344
Joined: Mon Aug 21, 2006 12:40 am
Location: Pittsburgh, PA

Post by burger2227 » Tue Dec 16, 2008 11:31 pm

The variable used IN the calculation does not matter! It could be an Integer and still give you a Double inaccuracy.

Exponents always return Double values in QB.

Now if you assign the calculation to a Single variable, it is stripped of the small Double inaccuracy.

A = i% ^ 2 'is a Single variable value that will match an integer

Ted
Please acknowledge and thank members who answer your questions!
QB64 is a FREE QBasic compiler for WIN, MAC(OSX) and LINUX : https://www.qb64.org/forum/index.php
Get my Q-Basics demonstrator: https://www.dropbox.com/s/fdmgp91d6h8ps ... s.zip?dl=0

Ralph
Veteran
Posts: 148
Joined: Fri Feb 09, 2007 3:10 pm
Location: Katy, Texas

Post by Ralph » Wed Dec 17, 2008 12:23 am

O.K. Then why does this give a small difference for ALL values of i for the first difference, and, except for i = 1.4 and 1.8, gives 0 for all other values of i for the second difference. ALL the values of i are single precision.

Code: Select all

FOR I = 1 TO 2 STEP 0.1
  A = I^2
  PRINT I, A-I*I, I^2 -I*I
NEXT I
Ralph, with QuickBASIC 4.5, operating under Windows XP, wiht anHP LaserJet 4L Printer. Bilingual in English/Spanish

User avatar
burger2227
Veteran
Posts: 2344
Joined: Mon Aug 21, 2006 12:40 am
Location: Pittsburgh, PA

Post by burger2227 » Wed Dec 17, 2008 3:33 am

Those are small accuracy differences.........Real small! Try this:

Code: Select all

FOR I = 1 TO 2 STEP .1
  A = I ^ 2
  B = I * I
  PRINT I, A - B, (I ^ 2) - B
NEXT I
Now the differences are mostly in the second calculation. The Double one!

Ted
Please acknowledge and thank members who answer your questions!
QB64 is a FREE QBasic compiler for WIN, MAC(OSX) and LINUX : https://www.qb64.org/forum/index.php
Get my Q-Basics demonstrator: https://www.dropbox.com/s/fdmgp91d6h8ps ... s.zip?dl=0

roy
Veteran
Posts: 55
Joined: Sun Jul 29, 2007 2:39 pm
Location: London

Post by roy » Wed Dec 17, 2008 5:08 am

Ralph, computers struggle with decimals because of the way that bits are divided into packets of eight. This program may show better the way that the computer handles Single,Double precision and decimals that are an eigth of 1.

CLS
DIM i AS DOUBLE
REM Using double precision with decimals, very messy.
FOR i = 1 TO 4 STEP .1
PRINT i,
NEXT
PRINT
REM Using single precision with decimals, some of the mess is removed.
FOR k = 1 TO 4 STEP .1
PRINT k,
NEXT
PRINT
REM Using a decimal that fits with the computers bit pattern, no problems.
FOR i = 1 TO 4 STEP .125
PRINT i,
NEXT
SYSTEM
Last edited by roy on Fri Dec 19, 2008 6:12 pm, edited 1 time in total.

User avatar
burger2227
Veteran
Posts: 2344
Joined: Mon Aug 21, 2006 12:40 am
Location: Pittsburgh, PA

Post by burger2227 » Wed Dec 17, 2008 12:52 pm

Structure of QB Precision numbers:

Double precision (DOUBLE in QBASIC) 8 bytes = 64 bits:
Sign: 1 bit
Exponent: 11 bits
Mantissa: 52 bits

Single precision (SINGLE in QBASIC) 4 bytes = 32 bits:
Sign: 1 bit
Exponent: 8 bits
Mantissa: 23 bits

The mantissa holds all of the decimal point values. The Exponent of Single is 8 bits or ONE byte. Thus it does not have the same Double error problem.

Ted
Please acknowledge and thank members who answer your questions!
QB64 is a FREE QBasic compiler for WIN, MAC(OSX) and LINUX : https://www.qb64.org/forum/index.php
Get my Q-Basics demonstrator: https://www.dropbox.com/s/fdmgp91d6h8ps ... s.zip?dl=0

Ralph
Veteran
Posts: 148
Joined: Fri Feb 09, 2007 3:10 pm
Location: Katy, Texas

Post by Ralph » Thu Dec 18, 2008 5:39 pm

Roy and Ted's explanations make some sense to me, but, why don't the following three FOR/NEXT loops give the identical exaxt values for ALL three cases? Notice that the first one gives exact values for 1 through 2.7, the second one for 1.5 through 2.5, and the last one for 2.3 through 2.7

Code: Select all

CLS
PRINT
REM Using single precision with decimals, some of the mess is removed.
DIM k AS SINGLE
FOR k = 1 TO 4 STEP .1
PRINT k,
NEXT

PRINT
FOR k = 2 TO 4 STEP .1
PRINT k,
NEXT
PRINT

PRINT
FOR k = 2.3 TO 4 STEP .1
PRINT k,
NEXT
PRINT
Ralph, with QuickBASIC 4.5, operating under Windows XP, wiht anHP LaserJet 4L Printer. Bilingual in English/Spanish

roy
Veteran
Posts: 55
Joined: Sun Jul 29, 2007 2:39 pm
Location: London

Post by roy » Fri Dec 19, 2008 4:22 am

I would not attempt to work out why or how a team of programmers came up with the logic that they did to solve this problem. If I set a problem that was unsolvable to four different teams and asked them to get the best solution, I would likely get four different solutions.
Last edited by roy on Fri Dec 19, 2008 4:51 pm, edited 1 time in total.

User avatar
burger2227
Veteran
Posts: 2344
Joined: Mon Aug 21, 2006 12:40 am
Location: Pittsburgh, PA

Post by burger2227 » Fri Dec 19, 2008 1:23 pm

Because you are using tenths instead of eigth's as Roy explained before. The Single exponent value matches 8 bits as in this example:

Code: Select all

CLS
PRINT
REM Using single precision with decimals, some of the mess is removed.
DIM k AS SINGLE
FOR k = 1 TO 4 STEP .125
PRINT k,
NEXT

PRINT
FOR k = 2 TO 4 STEP .125
PRINT k,
NEXT
PRINT

PRINT
FOR k = 2.25 TO 4 STEP .125
PRINT k,
NEXT
PRINT
A tenth creates a Single accuracy error.

Ted
Please acknowledge and thank members who answer your questions!
QB64 is a FREE QBasic compiler for WIN, MAC(OSX) and LINUX : https://www.qb64.org/forum/index.php
Get my Q-Basics demonstrator: https://www.dropbox.com/s/fdmgp91d6h8ps ... s.zip?dl=0

Ralph
Veteran
Posts: 148
Joined: Fri Feb 09, 2007 3:10 pm
Location: Katy, Texas

Post by Ralph » Fri Dec 19, 2008 10:14 pm

O.K/., I'll stop here, based on Roy's "back to reality" explanation, and on Ted's pieces of eight.
Ralph, with QuickBASIC 4.5, operating under Windows XP, wiht anHP LaserJet 4L Printer. Bilingual in English/Spanish

moneo
Veteran
Posts: 451
Joined: Tue Jun 28, 2005 7:00 pm
Location: Mexico City, Mexico

Post by moneo » Fri Dec 19, 2008 10:19 pm

qbasicfreak wrote:This is really a dumb question but how can you check if a number is a multiple of 2? I've tried everything I could think of.

ie.
IF string% = 'divisible by 2' THEN

Thanks
Qbasicfreak
Saying that a number is a multiple of 2 is the same as saying that the number is even.

Assuming that the number is a integer, here's a simple way of determining whether it is odd or even.

defint a-z
IF Number AND 1 THEN
PRINT "Number is odd"
ELSE
PRINT "Number is even"
END IF

However, this method will consider the Number zero as even.

How it works. If the low order bit of a number is a one, then the number is odd, otherwise it's even.
So, when you AND with a 1, if the low order bit of the Number is also a one, then the ressult of "Number AND 1" gives you a TRUE condition which means that the Number is odd. Otherwise, the low order bit is zero, which means that the Number is even.

Regards..... Moneo
If you are ahead of me, lead.
If you are behind me, follow.
If you are not doing anything,
Get out of the way.

Ralph
Veteran
Posts: 148
Joined: Fri Feb 09, 2007 3:10 pm
Location: Katy, Texas

Post by Ralph » Wed Dec 24, 2008 6:18 pm

Hello,, Moneo!

Here is another quirk I find in QuickBASIC 4.5.
I ran the code in G-W BASIC, and got Odd. 0, ODD, odd, 0, A is odd.
I ran the code in QuickBASIC and got Odd, -1.734723E-18, EVEN, even, -1.734723E-18, A is odd.

So, the value that qb returns for 5 ^ 2 is not truly the integer 25, since the above shows that the difference is not 0.

It seems to me that your use of AND to detect odd or even would not be proper in qb, since further use of 5 ^ 2 as an integer would not be true in qb.

To truly get the exact integer 25, I find that Ted's answer of assigning a variable to it, seems to be the only way to go.


[code[CLS
IF F ^ 2 AND 1 THEN PRINT "Odd" ELSE PRINT "Even"
PRINT 5 ^ 2 - 25
IF 5 ^ 2 - 25 = 0 THEN PRINT "ODD" ELSE PRINT "EVEN"
IF INT(5 ^ 2) - 25 = 0 THE PRINT "odd" ELSE PRINT "even"
A = 5 ^ 2
IF A = 25 = 0 THEN PRINT "A is odd" ELSE PRINT "A is even"
Ralph, with QuickBASIC 4.5, operating under Windows XP, wiht anHP LaserJet 4L Printer. Bilingual in English/Spanish

Post Reply