Qbasicnews.com

Full Version: Rotate left 2 bits (like assembler)
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3 4 5 6 7 8 9 10
Quote:....
I offer thee, good sir, my most sincere appologies.

I shall refrain from posting in any topic unless I offer a solution to the problem at hand.

I shall also in the upcoming future refrain from posting in any topic that was started more than two weeks ago.


Again, I deeply appologize for my irrational behaviour, and swear, as God is my witness, to become a better forum member from now on.

Thank you for showing me the true path to follow, so I may redeem and better myself.


Thank you.

:roll:
No need for apologies, we all are entitled to our opinions.

Thanks for your kind, elegant words.
*****
As I am unsure if you just missed the whole point, or if you're trying to make a joke that doesent suit you.

I'll explain it:
I was being sarcastic and ironic.
Quote:Ok, here's my solution. Similar to Mango's solution, it is not the most elegant, is very straighforward, but it works.
Code:
REM NOTE: X is the input 16 bit value to be rotated 2 left.
REM            X2 is the output 16 bit value as an integer.

dim x as long
dim x2 as integer
dim hexC000 as long
dim hex3FFF as long
dim top2 as long
dim bot2 as long

hexC000=&HC000&             'Bit mask to isolate 2 high-order bits
hex3FFF=&H3FFF&             'Bit mask to remove  2 high-order bits

top2 = x and hexC000        'Isolate 2 high-order bits
bot2 = top2 / 2^14          'Position 2 high-order bits into 2 low-order bits

x = x and hex3FFF         'Remove 2 high-order bits from x (just in case)
x = x * 2^2               'Shift x left 2 bits
x = x or bot2             'OR in the 2 low-order bits            

REM X is the final result as long.
x2 = x                       'x2 is the final 16 bit result as integer
*****
Moneo,

I may be missing something...a little drunk and I didn't run your code...just looked at it. Doesn't this code fail to work with negative numbers?


for example if I make x = 1000 0000 0000 0000 xxxx xxxx xxxx xxxx, then where does the 1 in the 32nd bit get rotated. This was the reason I explicitly wrote my code to work with 16-bit numbers....or...do you somehow "cast" the 32-bit to 16-bit?
??

Anyway...I took the challenge at face value and did the rotation in the 16-bit domain...which is why I made the comment about how it'd be simpler if unsigned data-types were available (which can be simulated by moving to the 32-bit domain).

cheers all

mango
Quote:Hey guys, I think we have a confusion here.

The original challenge said: "take a given 16 bit value and do a rotate left 2 bits."

In QB, a 16 bit value implies working with an INTEGER.
If we were working with a LONG, we would be working with 32 bits.

Yes, an INTEGER of -32768 has the same bit pattern as a LONG of 32768, as does an INTEGER of -4 and a LONG of 65532. BUT, both these INTEGERS have the sign bit (bit 15) set to 1, which for an INTEGER means that this is a negative number.

Therefore, if you compared an INTEGER of -32768 to a LONG of 32768, they would not be equal, because the compare is arithmetic, not bit-wise.
If you did an XOR of the INTERGER with the LONG, you would get a zero result showing that the bit patterns are equal because the leading zero bits of the LONG are ignored.

For the testing of the solutions submited, I put the code into a loop, comparing the results against proven results. So, if the submitted code produces answers expressed as LONG, they won't compare with the proven results in INTEGER, when these INTEGERS are negative. That's the problem.

So, for future solutions, please submit code that produces 16 bit values only in integers.
*****
1xxx xxxx xxxx xxxx (bin-16) == 1000 0000 0000 0000 0xxx xxxx xxxx xxxx (bin-32) which (i think) makes this rotate not work in all cases....or does the 16-bit get "dynamic_cast" (not 'reinterpret_cast')) to a 32-bit signed integer when the function is called? I made my solution to avoid any such issues...sticking strictly to the 16-bit domain.

cheers
Mango,

You're right. The way it is, it won't work for negative long integer values. My solution as it stands, is incorrect.

My test program has a FOR LOOP for an integer value from -32768 to 32766. Within this loop, each of these integer values is stored into the long integer value called X at the top of my solution routine. So, the routine will never have input with a 32 bit negative number, nor any value greater than a 16 bit integer.

BTW, I never ran into this problem before, but if you set up an integer FOR LOOP to 32767, it loops forever. Since at the last iteration it increments and then tests, the increment make it wrap around. That's why I tested up to 32766 only. You learn something every day.
*****
Btw, your solution overflows when bit 13 is set.
Blitz, it runs ok for me.

Did you take into consideration what I said in my previous post? That is, the input 16 bit integer value is assigned to the starting "x" long integer before starting the routine. Likewise, the resulting long value in "x" is assigned to a final integer variable.

Let me know if that helps it run ok.
*****
Quote:As I am unsure if you just missed the whole point, or if you're trying to make a joke that doesent suit you.

I'll explain it:
I was being sarcastic and ironic.
Z!re,

Considering the source, I suspected that you were being sarcastic, but since you said it so eloquently, I decided to accept it at face value. Your statements show that behind that hard shell, you have sound fundamental values.
*****
Quote:
Code:
x = x and hex3FFF         'Remove 2 high-order bits from x (just in case)
x = x * 2^2               'Shift x left 2 bits

i don't know why you "remove" your 2 high order bits hehe. but it would definetly fit as a new thedailywtf.com post hehe... let's see...

i'm lazy so i use a 4 bit nibble

1100 shl 2

0000

hm.... seems like that shl removed(!) the leading two 11 magically, nah you are right from an assembler point of view one can never be sure what that vodoo cpu does, let's better remove the uppermost 2 bits by hand...

oh and even your solution is actually a one liner... but i guess this way it's easier to "understand" the complicated matter of "rotating to bits left" (sounds like a good movie title to me)
Code:
valu% = 1

CLS

t$ = HEX$(valu%)
t$ = STRING$(4 - LEN(t$), 48) + t$

FOR a = 1 TO 4
p$ = MID$(t$, a, 1)
IF p$ = "0" THEN n$ = n$ + "0000"
IF p$ = "1" THEN n$ = n$ + "0001"
IF p$ = "2" THEN n$ = n$ + "0010"
IF p$ = "3" THEN n$ = n$ + "0011"
IF p$ = "4" THEN n$ = n$ + "0100"
IF p$ = "5" THEN n$ = n$ + "0101"
IF p$ = "6" THEN n$ = n$ + "0110"
IF p$ = "7" THEN n$ = n$ + "0111"
IF p$ = "8" THEN n$ = n$ + "1000"
IF p$ = "9" THEN n$ = n$ + "1001"
IF p$ = "A" THEN n$ = n$ + "1010"
IF p$ = "B" THEN n$ = n$ + "1011"
IF p$ = "C" THEN n$ = n$ + "1100"
IF p$ = "D" THEN n$ = n$ + "1101"
IF p$ = "E" THEN n$ = n$ + "1110"
IF p$ = "F" THEN n$ = n$ + "1111"
NEXT
rot$ = RIGHT$(n$, 14) + LEFT$(n$, 2)
n$ = ""
FOR a = 0 TO 3
p$ = MID$(rot$, 1 + a * 4, 4)
IF p$ = "0000" THEN n$ = n$ + "0"
IF p$ = "0001" THEN n$ = n$ + "1"
IF p$ = "0010" THEN n$ = n$ + "2"
IF p$ = "0011" THEN n$ = n$ + "3"
IF p$ = "0100" THEN n$ = n$ + "4"
IF p$ = "0101" THEN n$ = n$ + "5"
IF p$ = "0110" THEN n$ = n$ + "6"
IF p$ = "0111" THEN n$ = n$ + "7"
IF p$ = "1000" THEN n$ = n$ + "8"
IF p$ = "1001" THEN n$ = n$ + "9"
IF p$ = "1010" THEN n$ = n$ + "A"
IF p$ = "1011" THEN n$ = n$ + "B"
IF p$ = "1100" THEN n$ = n$ + "C"
IF p$ = "1101" THEN n$ = n$ + "D"
IF p$ = "1110" THEN n$ = n$ + "E"
IF p$ = "1111" THEN n$ = n$ + "F"
NEXT
num% = VAL("&H" + n$)

PRINT num%

Seeing as none of you managed to produce a working algorithm..

I guess I win..


It can even be made simpler by using a hex lookup table.. but I was lazy..
Pages: 1 2 3 4 5 6 7 8 9 10