Moneo


« on: July 14, 2003, 01:40:49 PM » 

The following anomaly occurs in QuickBasic 4.5. Does anyone know why this happens? DEFLNG az dim a as integer dim n as integer
n = 128
rem The following two instructions work perfectly:
a=log(n)/log(2) if 2^a = n then print n, "is a power of 2"
rem The following instruction, which is a combination of the above, DOES NOT WORK.
if 2^(log(n)/log(2)) = n then print n, "is a power of 2"
I don't understand. Why does it work separately but not combined? Thanks. *****



Logged




na_th_an


« Reply #1 on: July 14, 2003, 01:44:15 PM » 

Dunno, but maybe the result of log(n)/log(2) isn't integer, hence the error. a is integer, so a = log(n)/log(2) will perform an implicit INT(log(n)/log(2)), and, generally: 2^INT(log(n)/log(a)) <> 2^(log(n)/log(a)) Check it out



Logged




Moneo


« Reply #2 on: July 14, 2003, 02:23:06 PM » 

Nathan, Your analysis makes perfect sense. So if I changed the failing instruction as follows, it should work. if 2^INT(log(n)/log(2)) = n then print n, "is a power of 2" WELL, IT DOES NOT WORK. ? Any ideas? *****



Logged




na_th_an


« Reply #3 on: July 14, 2003, 02:24:25 PM » 

Well, this time I HAVE NO CLUE!! : : Another QB bug?



Logged




Glenn


« Reply #4 on: July 14, 2003, 02:49:56 PM » 

It fails at n = 16384. However, changing INT to CINT makes it work for 16384. (CINT converts to INTEGER and rounds correctly. INT just truncates.)



Logged

ravelling Curmudgeon (geocities sites require copying and pasting URLs.) I liked spam better when it was something that came in a can. Windows should be defenestrated.



Moneo


« Reply #5 on: July 14, 2003, 02:55:26 PM » 

Glenn, If I put into a loop, it also works up to 1024, EXCEPT THAT 128 DOESN'T WORK.
When n=128, the one line combined instruction does not work with or without the INT. If I round the result inside the parentesis, it will work. But why do I need to do this when all the other numbers work without it? *****



Logged




Glenn


« Reply #6 on: July 14, 2003, 03:04:51 PM » 

don't store floating point numbers accurately (and LOG returns a floating point result). When n = 128, LOG(n) / log(2) should be 7 but what you get is something slightly less than 7. Similarly, if n = 16384, the result should be 14 but you get something slightly less than 14. So, INT truncates the result to 6 or 13. For the other values, you get a result slightly above the integer that math says you should get and so INT's truncation works. Instead of using CINT, the perhaps more insightful solution is to use
INT(LOG(n) / LOG(2) + .001)



Logged

ravelling Curmudgeon (geocities sites require copying and pasting URLs.) I liked spam better when it was something that came in a can. Windows should be defenestrated.



Agamemnus


« Reply #7 on: July 14, 2003, 03:38:45 PM » 

or just use code to get the max bits used.



Logged

Peace cannot be obtained without war. Why? If there is already peace, it is unnecessary for war. If there is no peace, there is already war." Visit www.neobasic.net to see rubbish in all its finest.



Glenn


« Reply #8 on: July 14, 2003, 03:45:06 PM » 

That right value isn't known a priori. He's in fact using code to get the number of bits used.



Logged

ravelling Curmudgeon (geocities sites require copying and pasting URLs.) I liked spam better when it was something that came in a can. Windows should be defenestrated.



Moneo


« Reply #9 on: July 14, 2003, 03:46:13 PM » 

or just use code to get the max bits used. Sorry, I don't know what you mean. *****



Logged




Agamemnus


« Reply #10 on: July 14, 2003, 03:59:43 PM » 

128 uses 7 bits. 127 uses 7 bits. If 127 is less than 128, 127 isn't a power of 2.



Logged

Peace cannot be obtained without war. Why? If there is already peace, it is unnecessary for war. If there is no peace, there is already war." Visit www.neobasic.net to see rubbish in all its finest.



Moneo


« Reply #11 on: July 14, 2003, 04:08:45 PM » 

128 uses 7 bits. 127 uses 7 bits. If 127 is less than 128, 127 isn't a power of 2. I agree with your analysis, but how do I apply it to solving my posted problem? *****



Logged




Glenn


« Reply #12 on: July 14, 2003, 04:11:50 PM » 

truly amazing.



Logged

ravelling Curmudgeon (geocities sites require copying and pasting URLs.) I liked spam better when it was something that came in a can. Windows should be defenestrated.



Agamemnus


« Reply #13 on: July 14, 2003, 04:20:45 PM » 

because 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 and 16384 are all powers of two, and code (that I forgot) that gets the max bits used for a number (how many bits are needed to represent it) that is then subtracted from 2^those bits (or the array in the beginning) if equals zero, then it is a power of two. Or, do this: sub power.of.two% (n%): select case n% case 2, 4 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384 power.of.two% = 1 end select end function



Logged

Peace cannot be obtained without war. Why? If there is already peace, it is unnecessary for war. If there is no peace, there is already war." Visit www.neobasic.net to see rubbish in all its finest.



Moneo


« Reply #14 on: July 14, 2003, 06:19:56 PM » 

AGAMEMNUS, I know you're tying to help, but I'm not looking for alternate ways of determining if a number is a power of 2. I can already do that in the following 2 lines: DEFLNG az dim a as integer dim n as integer
a=log(n)/log(2) if 2^a = n then print n, "is a power of 2"
My problem is that I wanted to do it one line of code like this: if 2^(log(n)/log(2)) = n then print n, "is a power of 2" But, for some reason it doesn't work when n=128. The purpose of my post was to ask why this doesn't work. Nathan had a good idea, but it didn't solve the problem. *****



Logged




