Page 1 of 2
divisible by 2
Posted: Sun Dec 14, 2008 6:23 pm
by qbasicfreak
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
Posted: Sun Dec 14, 2008 6:48 pm
by Ralph
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"
USE MOD
Posted: Sun Dec 14, 2008 7:52 pm
by burger2227
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
Posted: Mon Dec 15, 2008 5:24 am
by qbasicfreak
Thanks,
qbasicfreak
Posted: Mon Dec 15, 2008 11:04 am
by Ralph
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"
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?
Posted: Mon Dec 15, 2008 1:20 pm
by burger2227
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
Posted: Mon Dec 15, 2008 9:45 pm
by Ralph
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
Posted: Mon Dec 15, 2008 11:11 pm
by burger2227
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
Posted: Tue Dec 16, 2008 11:00 pm
by Ralph
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.
Posted: Tue Dec 16, 2008 11:31 pm
by burger2227
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
Posted: Wed Dec 17, 2008 12:23 am
by Ralph
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
Posted: Wed Dec 17, 2008 3:33 am
by burger2227
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
Posted: Wed Dec 17, 2008 5:08 am
by roy
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
Posted: Wed Dec 17, 2008 12:52 pm
by burger2227
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
Posted: Thu Dec 18, 2008 5:39 pm
by Ralph
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
Posted: Fri Dec 19, 2008 4:22 am
by roy
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.
Posted: Fri Dec 19, 2008 1:23 pm
by burger2227
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
Posted: Fri Dec 19, 2008 10:14 pm
by Ralph
O.K/., I'll stop here, based on Roy's "back to reality" explanation, and on Ted's pieces of eight.
Posted: Fri Dec 19, 2008 10:19 pm
by moneo
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
Posted: Wed Dec 24, 2008 6:18 pm
by Ralph
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"