#Beginner having issues with bit manipulation.

162 messages · Page 1 of 1 (latest)

wary sluiceBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question run !howto ask.

#

@weak frost

Screenshots!

Your message appears to contain screenshots but no code. Please send code and error messages in text instead of screenshots if applicable!

eager coyote
#

@weak frost Delete this bro or else they will come for your neck!!

weak frost
#

Ope.

eager coyote
#

Post your code dont post screenshots. Trust me!.

weak frost
#

I can also drop the cpp file.

eager coyote
#

Yeah but dont forget to delete the screenshots

weak frost
#

Is it really that bad an idea? I thought it would be good to show in better detail what I'm talking about with examples of output???

eager coyote
eager coyote
wary sluiceBOT
#

@weak frost

Please Do Not Delete Posts!

Please don't delete forum posts. They can be helpful to refer to later and other members can learn from them. In the future you can use !solved to close a post and mark a post as solved.

river phoenix
#

@weak frost put the code back

weak frost
#

Hello, I'm a beginner trying to build my own method for taking a number, converting it to a binary array, and then displaying the elements of that array onto the console, the program then allows users to manipulate the bits therein, currently my program works pretty well with only one issue.

Problem
When the Toggle or Negate option is selected, a negative value ends up getting passed into my method that coverts the number to bits and displays it. This causes the wrong result being displayed. I've tried changing the data type relevant variables like bitField, a, and bitValue to types that can store larger numbers, but for some reason the number passed to a is always negative.

The toggle() method should turn the specified bit to a 1 or zero depending on it's current state using XOR, and the negate() method should cahnge every 1 to a 0 and every 0 to a 1 for the current binary array.

Question
My question is how can I address this? I've tried using unsigned long, unsigned long long, and double, but no container seems to be appropriate. This is for a project, and my course encourages independent research, so if someone could explain things rather than just fix it for me, or link some good videos to help with the issue, that would be greatly appreciated.

I've attached some screenshots of the code and the program in various states, and an example of the issue with the negative value shown in my watchlist. Thanks everyone for your time and help.

weak frost
wary sluiceBOT
#

@weak frost Has your question been resolved? If so, run !solved :)

river phoenix
#

@weak frost where do you see a negative number?

weak frost
#

That one got left out for some reason. sorry.

river phoenix
#

use unsigned bit if you don't want negatives

weak frost
#

a and bitField are negative here, they need to be positive to work properly.

#

There's a bit data type?

river phoenix
#

use unsigned values

#

the problem is that with int, the most significant bit is used as a sign bit

#

so when you flip it your value "becomes" negative

weak frost
river phoenix
#

yes

weak frost
#

Applying that now

weak frost
# river phoenix yes

I'm not sure that fixed it. I'm using unsigned variables in the toggle method and it generates these crazy garbage numbers.

river phoenix
#

why do you think it's garbage?

#

what did you do to get these values?

river phoenix
#

@weak frost bro you okay?

muted aurora
#

also, shouldn't isolator be the same type as bitField

weak frost
#

Because it doesn't return a binary representation that is the same as the original except the specified bit has been toggled. In the case shown here, the output should be

0000 0000 0000 0000 0101 1001 1001 1111.

The toggleBit(int bit) method is a method which shows the user the binary for the number they entered at the beginning of the program, then asks them to enter a number between 1 and 32, this is taken in as the bit to be toggled on or off depending on its current state. an unsigned int called isolater is initialized as 1 left shifted by the value stored in bit, this generates a binary number with 1 in the same bit position as the bit we want to toggle in our bitField,

so if bit = 1 like in the example, then isolator will be a number whos binary representation is

0000 0000 0000 0000 0000 0000 0000 0001

then bitField is assigned as a value equal to (~isolator) ^ bitField.

so in the example shown the operation should look like

       1111 1111 1111 1111 1111 1111 1111 1110

XOR 0000 0000 0000 0000 0101 1001 1001 1110

which should be 0000 0000 0000 0000 0101 1001 1001 1111.

This would then be displayed in the console along with a message saying which bit was toggled.

Sorry, it took a while to type this out and verify the code should definitely be working. Hopefully this answers everything.

river phoenix
#

I think you got xor wrong

#

it's the opposite

weak frost
#

So then I shouldn't be negating isolator.

river phoenix
#

no

weak frost
#

That did it, I was wrong about how XOR worked. The toggle(int bit) method now works as it should.

Did you have any insight about the negate() method? It should literally just do NOT bitField and then print the binary for that to the console.

river phoenix
#

the negate looks correct

#

double bitValue = pow(2, i + 1);

#

I don'T think that's right

weak frost
#

The output should be an inverted binary.

river phoenix
#

I think your conversion or print function is wrong

river phoenix
#

because it's not printing the right thing lol

#

why are you using a double?

muted aurora
#

why does you conversion function take in bitField as an int

#

actually, why do you pass it in when you have it as a global variable in the first place....?

weak frost
# river phoenix why are you using a double?

lol Because I'm not entirely confident in how to write in C++ yet, so I very well may have just made a few incompetent choices. Please feel free to explain why it doesn't make sense and what I could do better. It'd be leagues above the help I've managed to get thus far.

weak frost
river phoenix
#

@weak frost I would avoid the pow and just use bit shift to go over the bitfield

#

I would also get rid of the "conversion" method and do it in print directly

muted aurora
#

By the way, if you're on C++20 then you can just do std::format("{:b}", bitField)

weak frost
muted aurora
#

your conversion method isn't even a conversion method lol

#

generally I'd expect a function named convert to uh return a value

river phoenix
weak frost
# muted aurora generally I'd expect a function named `convert` to uh return a value

Glad to know my educational investment is paying off so well. So level with me then, walk me through this, because I thought I was onto something and that notion was validated. Like I said, the program starts by asking the user for a number, makes sure it won't break the program by running it through validate(), then is prints the number as binary using the convert and print methods, then a menu that allows the user to manipulate bits. We cannot use bitset and such.

#

And give me the details, like I'm a moron. Cause I gotta actually learn this, I don't just wanna be fed the answers, yknow?

river phoenix
#

Well you could just have a print function

#

No need for convert in between

weak frost
#

That's too brief, I need the details. lol

river phoenix
#

That's really it

#

And to iterate on the bits

#

Rather than doing that pow and division

#

You can do

#

const bool isSet = number & (1 << x);

weak frost
# river phoenix That's really it

Well, if you could explain what I could do instead, and then also why and how it accompishes what I'm trying to do, and maybe even shoot some links my way, that woulld be superb. lol

river phoenix
#

You just don't need that function

#

If you want to print then you should call the print function not the comvert function

#

So put the logic in the print function

weak frost
#

I dont know anything about the print function in C++.... They taught us all that using C#....

muted aurora
#

wat

river phoenix
#

It's your own print function

weak frost
#

You're talking about the printBinary() method I have?

river phoenix
#

Yes

weak frost
#

You're saying just put the logic from the 'convert' method in there and then just nixing the seperate method.

muted aurora
#

yes

weak frost
#

You guys are awesome. Okay that makes sense.

weak frost
# muted aurora wat

Yeah man, don't get me started. This is a bigger name college and I've just been lost the entire program. Got damn near a 4.0, but I'll be damned if I can get a teacher to sit down and explain this stuff to me. That GPA is me moving the wieght all by myself. lmao.

#

I called the advocacy team and even they said pretty much the same thing you did.

muted aurora
river phoenix
#

@weak frost you're doing a great job trying to learn stuff

#

Keep on like that and continue asking for help when you're getting stucked

weak frost
# river phoenix Keep on like that and continue asking for help when you're getting stucked

Thanks! I got rid of the unnecessary method, but I still have the negate that isn't outputting what I would expect, that being the inverted version of the binary representation. If its a 0 it becomes a 1, and 1becomes 0 for the whole bitfield. You said some stuff about there being an iisue with the logic in how I print out the binary and something else, could we go back to that?

muted aurora
#

could you show what your print function looks like now?

weak frost
#

Sure thing!

#

Here also is the updated cpp.

weak frost
muted aurora
#

@weak frost
Take this for example

void printBinary()
{
    const int numBits = sizeof(bitField) * 8;

    for (int i = numBits - 1; i >= 0; --i)
    {
        auto bit = (bitField >> i) & 1;
        std::cout << bit;
    }
}

Instead of pow, just shift

#

I have no idea if this actually works since i didn't test it lol but it should convey the concept

weak frost
#

Hmmm, you might have me lost again. The way they're teaching us, when you convert a number to binary, you're essentially dividing the number by a power of two, if the number can fit, its a 1 and you subtract the power of 2 value if not then its 0 and you move on to the next bit until you get to 2to the 0, then you have a completed binary conversion.

muted aurora
#

Eh... that sounds kind of overcomplicated to me. I mean, it sounds like it'd work, but why do all that when you can directly bit-mask the bit you want?

weak frost
muted aurora
#

oof

weak frost
# muted aurora oof

I was told my code looked great after asking for help, it still didn't even work properly.

#

So what are you doing here in this example you sent me? can you walk me through it?

muted aurora
#

It's basically just (bitField >> i) & 1 that's important here

#

it shifts bitField right by i spots, and then takes the lowest bit - which was the ith bit of bitField

#

it just loops over all the bits from highest to lowest (since we want to print the highest bit first)

weak frost
#

Can you explain how it does that a little more? I've really been struggling to internalize and visualize how all the shifting and bitwise operators work.

#

Ugh, I keep forgetting to hit reply. sorry.

muted aurora
#

Lets say you have the bits 0100 and you want the 2nd bit from the right (0 indexed)
shift right by 2 bits: 0100 >> 2 -> 0001
take the last bit: 0001 & 1 -> 1

weak frost
muted aurora
#

Just ditch it, yeah

#

there's no real point in filling an array just to print it when you can just print each item directly

#

yup!

weak frost
#

I'm getting it!

weak frost
# muted aurora yup!

Looking good, but when I did that I lost some of the formatting, know how I can reincorporate the bit I had where it grouped them into 4s? Could I just do the if but with i for the modulo or something?

muted aurora
#

Yup

weak frost
muted aurora
#

i is just used as an index variable, basically

#

try it and see :)

weak frost
#

It works!

#

Thank you so much for breaking that all down for me!

muted aurora
#

np :)

#

glad you got it working

weak frost
muted aurora
#

(though obligatory don't ask to ask, just leave a message lol)

weak frost
# muted aurora I am

Think you could help me with something else real quick? I'm trying to make a catch for my turn on and turnoff methods that checks to see if the bit in question is already on or off respectively, before going in and performing an operation. The Turn on method works perfectly, but I'm having issues with my turn off method. Do you think you could help me understand why? I feel like XOR is the right check to make, but I'm expecting the value of bit to be a 1 or a 0 and it's not, instead it's a large int.

muted aurora
weak frost
#

Because if bitEval equals 0 I want it to turn on the bit, and if bitEval equals 1 I want it to say the bit was already off. I looked at a truth table and the only operator that fits is XOR because 0^1 = 1 and 1^1 = 0.

#

Right?

muted aurora
#

Let me rearrange your code a bit:

// Let bitField = 0b1101, index = 2
int isolator = 1 << index - 1; // what is isolator?
int bitEval = bitField ^ isolator; // what are the two operands to the xor?
muted aurora
#

yup

weak frost
#

Which would be 1111

#

?

muted aurora
#

exactly

weak frost
#

Which is very wrong.

#

So instead I should be using & still? Or should I be negating somewhere maybe?

muted aurora
#

Let me answer with a question, how does your turnOnBit function do its check?

#

specifically, what does bitEval mean in that function?

weak frost
#

If bitEval == 0 that means the bit was on and needs to be shut off, so I do bitField = bitField & (~isolator);. If bitEval == 1 then the bit is already turned off and I just out a message saying that.

weak frost
#

I was thinking the operation I have to assign a value to bitEval would esentially take the current bitField and then do a bitwise operation on it against a number = to 1 leftshifted by index-1. Then that value will be either 1 or 0 and get's passed to the if statement.

#

Like.

bitfield: 1101
index: 2
(1 << index -1) 0010

1101
^0010

1111

1101
&0010

0000

1101

0010
1111

So I'm at a loss. lol

muted aurora
#

But as you've figured out, that method doesn't work, since that xor doesn't give 1 or 0

#

What does your turnOnBit function do?

weak frost
#

Could I use & and then just siwtch the conditions of the if statements?

muted aurora
#

Maybe 👀

weak frost
#

Gonna test this.

muted aurora
#

The thing I wanted to allude to is that at a high level, the turnBitOn function goes something like this:

  • get the nth bit
  • if the nth bit is 0
    • turn it on
  • else
    • print a message
weak frost
#

You really helped me understand bit manipulation more in depth! I really appreciate your time!

wary sluiceBOT
#

Thank you and let us know if you have any more questions!

This thread is now set to auto-hide after an hour of inactivity

glossy spindle
# eager coyote Post your code dont post screenshots. Trust me!.

So I know you're probably trolling @eager coyote but let's set the record straight for the new person on the server (and welcome @weak frost).
It is in our #rules that screenshots and photos especially of code, error messages, etc. should not be sent. Don't be lazy, just copy-paste. The bot tells people about this. You were warned because you repeatedly asked the same exact question with the same exact photos (the worst photos I've ever seen, just for the record) and were repeatedly told to stop sending the photos.

weak frost
#

Ope...

river phoenix
#

@weak frost tbh I found you were great at describing your problem and trying to add details

glossy spindle
#

ditto

glossy spindle
weak frost
#

They're pretty stringent about that at my school. Lol Real sticklers for all the traditional conventions.