#Setting a range of bits to 0

102 messages · Page 1 of 1 (latest)

nocturne rock
#

Context: Given 4 params (value, high, low, isSigned) I need to return a number that takes the bits from the given range (high - low)

So I have a 32 bit int, and the lo is 4 and the high is 7

My initial thought was to just do

value = value >> low;

Which is able to get the bits in the correct place (at the front of the bitfield), but now my problem is that I need the rest of those bits that are not included in the range to be 0.

silent lance
#

hmmm

peak nacelle
#

You're on the right track.

silent lance
#

so give examples of what the fn is supposed to do @nocturne rock

#

im kinda confused

nocturne rock
#
COMMAND:
./testField getField 0x000012B4 7 4 0

ARGUMENTS:
old      = 0x000012B4 = 0000 0000 0000 0000 0001 0010 1011 0100
hi       = 7
lo       = 4
isSigned = 0 (unsigned)

RETURN:
         = 0x0000000B = 0000 0000 0000 0000 0000 0000 0000 1011
silent lance
#

hmmm

#

what does 4 do

nocturne rock
#

oh it doesnt show the underlines

#

so the 4 points to the start of the range of bits we want to move

silent lance
#

but then why is there no 0001 0010 or 0100

nocturne rock
peak nacelle
#

hint: use &

nocturne rock
#

thank you, I should have mentioned that this is school and I don't want to cheat

#

let me think for a bit

peak nacelle
#

we always avoid giving full solutions

#

very common to use & to apply a "mask" to the bits you care about

nocturne rock
#

right

#

I think part of it is that I implemented a method that does that and so im limiting my self to what ive already done

#
int getBit (int value, int position) {
    //for some reason this returns the value at the position that 1 is
    //so bit 2 in 00000000000000000001001000111100 would return 4, which is the decimal for the number that the 1 at that position represents.
    int temp = value &= (1 << position);
    if(temp != 0){
        return 1;
    }
    return 0;
}
peak nacelle
#

this seems like a different method

nocturne rock
#

yeah it is

#

like idk how to explain my thinking but like

#

like bitmasks make sense

#

and so in that method im just pushing a 1 to the place where I want to make the logical AND comparison

deep saffron
#

aaaah, I finally understood it. So basically when you have a number 0b0001_0010_1010 and you have the range low, high then you want to get the lower bits from low (inclusive) to high (inclusive), so f.e. low=1, high=3 would take these bits and interpret it as a new number (I marked the bits that you want with an X):

0b0101_0110_1100
            XXX
```So you'd want to have `110` (= 6)?
#

have I understood your question correctly?

nocturne rock
#

yes, except the masks start at 0 iirc

deep saffron
#

updated the values. is it now correct?

nocturne rock
#

yes

#

for now once I figure out how to set this range of bits to 0 that I want I can apply it to the rest of the problem since down the line ill have to take 2's compliment and stuff

#

and sign it

#

so using logical AND here given that we have the original value and the value bitshifted to the place in front

deep saffron
#

Setting unwanted bits to 0 is easy, f.e. for the example I showed you already you can either use this bitmask

0b0000_0000_1110
```and then shift the resulting bits downwards like you already did, or you first shift it downwards and then use this bitmask
```java
0b0000_0000_0111

Obviously this bitmask only works for low=1, high=3, you'll have to figure out a way to generate this bitmask

#

All you need to do with this bitmask is to AND your value with it to zero all bits that are not 1 in the bitmask

nocturne rock
#

ok I think I know what to do

#

im gonna do a janky way and ill see if we can optimize it

deep saffron
#

Example:

value := 0b1010_0010_0110
low := 2
high := 6
=> 
value AND bitmask
=>
  0b1010_0010_0110  (value)
& 0b0000_0111_1100  (bitmask)
------------------------------
  0b0000_0010_0100  (result with bits destroyed where mask wasnt 1)
#

It's probably easier to first shift the value down like you did already, and only then apply the bitmask, just because it can be done with a little less code (not entirely sure, but at least the naive versions that my head just created).

nocturne rock
#

ok

#

so this is super janky

#

BUT

#

I have a bitfield now where its all 1's in the positions I want

#

so then I just do &

#

and then it should clear everything except for the places I want

deep saffron
#
value &= bitmask```
nocturne rock
#

yep

deep saffron
#

This works because AND only gives a 1 if both bits are 1, so if one bit is 0 then the resulting bit is always 0

nocturne rock
#

ok fantastic it works

deep saffron
#

congratulations

nocturne rock
#

and there is a new problem, so im returning the right thing now, but it wants all 32 bits

#

where im returning 0xB

#

it wants

#

0x0000000B

deep saffron
#

but... these are the same

#

or do you return a string?

nocturne rock
#

well wait bc

#

I was working with 2 32 bit fields

#

so did C just automatically remove the leading 0's?

deep saffron
#

Yes, because they are redundan

#

*redundant

nocturne rock
#

oh

#

then im fine

deep saffron
#

like, would you write 00002 or just 2?

#

it's the same principle, just in a different base (here base 10, for you base 16 [hexadecimal])

nocturne rock
#

yeah, im just looking at the directions

#

let me check smth

#

ok yeah we are ok

#

I hard coded the answer that they want

#

and it still returns the same thing

#

so

#

Well thank you very much @deep saffron and @peak nacelle

#

But I think we are good to go from here

deep saffron
nocturne rock
#

im still going to office hours tomorrow to discuss it but im in a great spot now

#

Cheers guys

deep saffron
#

wait

#

I found your solution

nocturne rock
#

ok im here

deep saffron
#

A simple printf change:

nocturne rock
#

oh yeah

#

well

#

so

#

for more context lol

deep saffron
#
printf("0x%08X", 0xB);
nocturne rock
#

im writing the implementations for a library

#

and we were told to not touch it

#

well wait

#

hmmm

deep saffron
#

oh yeah, this would be just for the printing part

nocturne rock
#
result   = getField(value, hi, lo, isSigned);
    printf("getField: get bits %d:%d from 0x%X (signed %d) = 0x%X\n", hi, lo, value, isSigned, result);
#

yeah they said to not edit this

#

and clearly they didnt include the 8

#

so we are A-Ok my fren

deep saffron
#

okay, if you wanted to have the 0s then you'd need to do %08X (0 means to pad with 0s, 8 means that it should have length 8 and X means a hexadecimal number where a, b, ... are printed in uppercase (as opposed to x for lowercase)

nocturne rock
#

understood

deep saffron
#

but since you were told not to touch it, you're good to go I guess

nocturne rock
#

yep

#

thank you for helping me out lads

#

have a great day / night monke