This is the code I am going to use to take a set of three booleans and convert it into an int for a switch statement:
int bits = 0;
bool a = true, b = false, c = true; // 101 = 5
bits = bits | a << 2;
bits = bits | b << 1;
bits = bits | c;
cout << bits;
I have eight cases based on the combined state of these three booleans. Am I doing this right?
Right, not in the sense of the syntax although if there are any problems there please advise. More right in the sense of "Is this the best way to solve this problem?"
If you are using C++, you could use bitset<N>.
You're doing it right. You could make the code a little more succinct though:
bits |= (a<<2) | (b<<1) | (c<<0);
Just be aware that the Standard doesn't enforce any size constraint on bool. Pragmatically speaking there shouldn't be a problem with three bits, but the Standard doesn't back you here.
$ cat ttt.c
//example of C solution
#include <stdio.h>
int main() {
union {
unsigned int val;
struct {
unsigned a : 1;
unsigned b : 1;
unsigned c : 1;
//unsigned d : 1;
//e, f, g, h...
} flags;
} bits;
bits.val=0;
bits.flags.a = 1;
bits.flags.c = 1;
printf("val: %d\n",bits.val);
return 0;
}
~$ ./ttt
val: 5
I would do it as:
bits = (bits << 1) | a;
bits = (bits << 1) | b;
bits = (bits << 1) | c;
which would require less maintenance work if you needed to add or to remove a flag.
However, doing this so that you can use it for a switch sounds like it might be a bad idea. Adding a flag would double the number of states you'd need to handle, and the case values would be fragile and hard to read.
But if you really must, here's another approach:
enum
{
c_bit_offset,
b_bit_offset,
a_bit_offset
};
unsigned int bits = (a << a_bit_offset)
| (b << b_bit_offset)
| (c << c_bit_offset);
switch (bits)
{
case 0:
/* Do something. */
break;
case (1 << a_bit_offset):
/* Do something. */
break;
case (1 << a_bit_offset) | (1 << b_bit_offset):
/* Do something. */
break;
...
}
By the way, you probably should use unsigned int instead of int.
You can make some defines to make easy to work with bits
#define BitSet(arg,bit) ((arg) |= (1<<bit))
#define BitClr(arg,bit) ((arg) &= ~(1<<bit))
#define BitFlp(arg,bit) ((arg) ^= (1<<bit))
#define BitTst(arg,bit) ((arg) & (1<<bit))
Then you can use only one char
keys = 0b00000101;
BitSet (keys,1);
This an common way to work in embedded systems.
You can always do the conversion explicitly:
bits = bits | (a ? 1 : 0) << 2;
However I believe C/C++ will handle it implicitly, once you're using the bit-shift operator.
You should define constants for each flag, giving a name to the bit you are setting:
const int a_flag = 2;
bits = bits | (a ? 1 : 0) << a_flag;
Edit:
As you can see from the comments on my answer, most C/C++ programmers prefer to learn implicit conversions and operator precedence. Therefore your original code is "most correct".
Edit 2:
Except, you should use the |= operator:
const int a_flag = 2;
bits |= a << a_flag;
Related
I now know how it's done in one line, altough I fail to realise why my first draft doesn't work aswell. What I'm trying to do is saving the lower part into a different variable, shifting the higher byte to the right and adding the two numbers via OR. However, it just cuts the lower half of the hexadecimal and returns the rest.
short int method(short int number) {
short int a = 0;
for (int x = 8; x < 16; x++){
if ((number & (1 << x)) == 1){
a = a | (1<<x);
}
}
number = number >> 8;
short int solution = number | a;
return solution;
You are doing it one bit at a time; a better approach would do it with a single operation:
uint16_t method(uint16_t number) {
return (number << 8) | (number >> 8);
}
The code above specifies 16-bit unsigned type explicitly, thus avoiding issues related to sign extension. You need to include <stdint.h> (or <cstdint> in C++) in order for this to compile.
if ((number & (1 << x)) == 1)
This is only going to return true if x is 0. Since 1 in binary is 00000000 00000001, and 1 << x is going to set all but the x'th bit to 0.
You don't care if it's 1 or not, you just care if it's non-zero. Use
if (number & (1 << x))
Currently I'm working on an NES emulator and I'm working on the CPU core. I've searched all over the internet, but I can't find the right keywords find the answer to my question, so I thought I'd ask it here. What I have is seven booleans that act as my processor status flags. The current opcode I'm working on wants me to push the processor status flags to the stack. My stack is of the unsigned char datatype. I thought I would be able to smash the booleans together like this:
bool C, Z, I, D, B, V, N;
unsigned char example;
example = {C, Z, I, D, B, V, N, 0};
That didn't work, so how do I go about putting all of my boolean processor status flags into an unsigned char datatype so I can push the flags onto my stack?
enum { C=0x01, Z=0x02, I=0x04, D=0x08,
B=0x10, V=0x20, N=0x40 };
unsigned char flags = 0;
This works because only one bit is set in each constant. To determine whether the flag is set, use (flags & FLAGNAME) like (flags & C) to determine if it is set. Be careful not to get the bitwise AND (&) I used confused with the Boolean/logical AND (&&). The && operator won't work in place of the & operator. To set a flag, use (flags |= FLAGNAME) and to unset it, use flags &= ~FLAGNAME;. Adjust the constants for the correct order, so the NES instruction can properly check the flags. After all, if they're not in the correct order, the wrong flag values may be used, which obviously would be a problem.
Also, don't forget the parentheses. The bitwise operators have very low precedence, so parentheses around the expression are essential.
If you don't know about the bitwise operators, they are worth reading up on.
Edit
A handy set of macros for you:
#define FLAG_ISSET(x) (flags & (x))
#define FLAG_SET(x) (flags |= (x))
#define FLAG_CLEAR(x) (flags &= ~(x))
...
if (FLAG_ISSET(C))
...
FLAG_SET(V);
FLAG_CLEAR(Z);
Try std::bitset. http://en.cppreference.com/w/cpp/utility/bitset I couldn't find a way to construct it using initializer lists, but you can always use the operator[] or set() to set each bit, and use to_ulong() to convert it to a number (then you can convert the unsigned long to an unsigned char trivially).
#include <stdio.h>
#include <bitset>
using namespace std;
int main()
{
bitset<7> reg;
bool C = true, Z = false, I = false, D = false, B = true, V = true, N = false;
reg[6] = C;
reg[5] = Z;
reg[4] = I;
reg[3] = D;
reg[2] = B;
reg[1] = V;
reg[0] = N;
unsigned char example = static_cast<unsigned char>(reg.to_ulong());
printf("0x%x\n", example);
return 0;
}
try this:
bool C, Z, I, D, B, V, N;
unsigned char example = 0;
if(C)
example |= (1 << 7)
if(Z)
example |= (1 << 6)
if(I)
example |= (1 << 5)
if(D)
example |= (1 << 4)
if(B)
example |= (1 << 3)
if(V)
example |= (1 << 2)
if(N)
example |= (1 << 1)
Let's say int status is your CPU status register.
You could create some defines like these:
#define CPU_REG_STATUS_C 0x00000040
#define CPU_REG_STATUS_Z 0x00000020
#define CPU_REG_STATUS_I 0x00000010
#define CPU_REG_STATUS_D 0x00000008
#define CPU_REG_STATUS_B 0x00000004
#define CPU_REG_STATUS_V 0x00000002
#define CPU_REG_STATUS_N 0x00000001
and then set/unset the flags indipendently from each other by using the bitwise binary operators & and |
example1: setting the ZERO flag
status |= CPU_REG_STATUS_Z;
example2: checking the value of the ZERO flag:
if(status & CPU_REG_STATUS_Z)
{
//zero flag is set
}
else
{
//zero flag is unset
}
however, there are plenty of CPU core source codes out there, especially for the 6502 CPU (Commodore C64, Nintendo NES and many others) so you have to bother only with the emulation of the console.
http://www.6502.org/tools/emu/
This may be a bit heavy to be putting in an emulator, but why not convert each boolean value into a bit in the character, then decode the character once you need to pull it off your stack.
unsigned char encodeBits(bool bools[8]) {
unsigned char retval = 0;
for(int i = 0; i < 8; i++) {
retval += (bools[i] ? 1 : 0);
retval = (i < 7 ? retval << 1 : retval);
}
return retval;
}
This code basically just shifts the boolean value into a character.
Then to decode, pass an empty array by reference,
void decodeBits(bool (&bools)[8], unsigned char input) {
for(int i = 0; i < 8; i++) {
bools[i] = (input & 0x00000001 ? true : false);
input = (i < 7 ? input >> 1 : input);
}
}
This code should compare the first bit of the character, then shift it etc. etc.
This can be done without arrays but for simplicity's sake I used arrays.
Edit: A working example: http://ideone.com/hQ47nn
This should be what you are looking for:
bool C, Z, I, D, B, V, N;
unsigned char example = 0;
const unsigned char mask = 0x01;
if(N)
example |= mask << 1;
if(V)
example |= mask << 2;
//...
if(C)
example |= mask << 7;
I know there are answers for this question using using gcc byteswap and other alternatives on the web but was wondering why my code below isn't working.
Firstly I have gcc warnings ( which I feel shouldn't be coming ) and reason why I don't want to use byteswap is because I need to determine if my machine is big endian or little endian and use byteswap accordingly i.,e if my machine is big endian I could memcpy the bytes as is without any translation otherwise I need to swap them and copy it.
static inline uint64_t ntohl_64(uint64_t val)
{
unsigned char *pp =(unsigned char *)&val;
uint64_t val2 = ( pp[0] << 56 | pp[1] << 48
| pp[2] << 40 | pp[3] << 32
| pp[4] << 24 | pp[5] << 16
| pp[6] << 8 | pp[7]);
return val2;
}
int main()
{
int64_t a=0xFFFF0000;
int64_t b=__const__byteswap64(a);
int64_t c=ntohl_64(a);
printf("\n %lld[%x] [%lld] [%lld]\n ", a, a, b, c);
}
Warnings:-
In function \u2018uint64_t ntohl_64(uint64_t)\u2019:
warning: left shift count >= width of type
warning: left shift count >= width of type
warning: left shift count >= width of type
warning: left shift count >= width of type
Output:-
4294901760[00000000ffff0000] 281470681743360[0000ffff00000000] 65535[000000000000ffff]
I am running this on a little endian machine so byteswap and ntohl_64 should result in exact same values but unfortunately I get completely unexpected results. It would be great if someone can pointout whats wrong.
The reason your code does not work is because you're shifting unsigned chars. As they shift the bits fall off the top and any shift greater than 7 can be though of as returning 0 (though some implementations end up with weird results due to the way the machine code shifts work, x86 is an example). You have to cast them to whatever you want the final size to be first like:
((uint64_t)pp[0]) << 56
Your optimal solution with gcc would be to use htobe64. This function does everything for you.
P.S. It's a little bit off topic, but if you want to make the function portable across endianness you could do:
Edit based on Nova Denizen's comment:
static inline uint64_t htonl_64(uint64_t val)
{
union{
uint64_t retVal;
uint8_t bytes[8];
};
bytes[0] = (val & 0x00000000000000ff);
bytes[1] = (val & 0x000000000000ff00) >> 8;
bytes[2] = (val & 0x0000000000ff0000) >> 16;
bytes[3] = (val & 0x00000000ff000000) >> 24;
bytes[4] = (val & 0x000000ff00000000) >> 32;
bytes[5] = (val & 0x0000ff0000000000) >> 40;
bytes[6] = (val & 0x00ff000000000000) >> 48;
bytes[7] = (val & 0xff00000000000000) >> 56;
return retVal;
}
static inline uint64_t ntohl_64(uint64_t val)
{
union{
uint64_t inVal;
uint8_t bytes[8];
};
inVal = val;
return bytes[0] |
((uint64_t)bytes[1]) << 8 |
((uint64_t)bytes[2]) << 16 |
((uint64_t)bytes[3]) << 24 |
((uint64_t)bytes[4]) << 32 |
((uint64_t)bytes[5]) << 40 |
((uint64_t)bytes[6]) << 48 |
((uint64_t)bytes[7]) << 56;
}
Assuming the compiler doesn't do something to the uint64_t on it's way back through the return, and assuming the user treats the result as an 8-byte value (and not an integer), that code should work on any system. With any luck, your compiler will be able to optimize out the whole expression if you're on a big endian system and use some builtin byte swapping technique if you're on a little endian machine (and it's guaranteed to still work on any other kind of machine).
uint64_t val2 = ( pp[0] << 56 | pp[1] << 48
| pp[2] << 40 | pp[3] << 32
| pp[4] << 24 | pp[5] << 16
| pp[6] << 8 | pp[7]);
pp[0] is an unsigned char and 56 is an int, so pp[0] << 56 performs the left-shift as an unsigned char, with an unsigned char result. This isn't what you want, because you want all these shifts to have type unsigned long long.
The way to fix this is to cast, like ((unsigned long long)pp[0]) << 56.
Since pp[x] is 8-bit wide, the expression pp[0] << 56 results in zero. You need explicit masking on the original value and then shifting:
uint64_t val2 = (( val & 0xff ) << 56 ) |
(( val & 0xff00 ) << 48 ) |
...
In any case, just use compiler built-ins, they usually result in a single byte-swapping instruction.
Casting and shifting works as PlasmaHH suggesting but I don't know why 32 bit shifts upconvert automatically and not 64 bit.
typedef uint64_t __u64;
static inline uint64_t ntohl_64(uint64_t val)
{
unsigned char *pp =(unsigned char *)&val;
return ((__u64)pp[0] << 56 |
(__u64)pp[1] << 48 |
(__u64)pp[2] << 40 |
(__u64)pp[3] << 32 |
(__u64)pp[4] << 24 |
(__u64)pp[5] << 16 |
(__u64)pp[6] << 8 |
(__u64)pp[7]);
}
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
C/C++ check if one bit is set in, i.e. int variable
e.g. if I had a integer and i wanted to check what the value of bits 20-25 were, or if i just wanted to check if one of the bits is 0 or 1, how would i do that?
Use standard logic operations such as logical ANDs, ORs, XORs and combine that with bit shifts. This should give you some ideas: http://en.wikipedia.org/wiki/Bit_manipulation
Hope that helps
You would use the bitwise-AND operator between the integer and a "mask" value, which ignores all the other bits. So something like this:
const int BIT_4 = 0x8;
// ....
int val = /* ... */;
if ((val & BIT_4) != 0)
; // Bit 4 is ON!
else
; // Bit 4 is OFF
You can do it by using bitwise AND operator.
int x = SOME_VALUE;
// check 20-25 bits
if ( x & 0x3F00000 ) {
// any of bits on
}
int bitsToInt(int value, int s, int e) {
int mask = ((1 << (e - s + 1)) - 1) << s;
return (value & mask) >> s;
}
bitsToInt(7, 2, 3) returns 1
thinking about it a bit more, if what you want is to stuff several values into one int you can be better off doing bitfields and have compiler worry about masks and shifts.
uint32_t
get_bits_20_to_24(uint32_t i_)
{
union {
struct
{
uint32_t bits1 : 20;
uint32_t bits2 : 5;
uint32_t bits3 : 7;
} s;
uint32_t i;
};
i = i_;
return s.bits2;
}
I'm working on a homework assignment for my C++ class. The question I am working on reads as follows:
Write a function that takes an unsigned short int (2 bytes) and swaps the bytes. For example, if the x = 258 ( 00000001 00000010 ) after the swap, x will be 513 ( 00000010 00000001 ).
Here is my code so far:
#include <iostream>
using namespace std;
unsigned short int ByteSwap(unsigned short int *x);
int main()
{
unsigned short int x = 258;
ByteSwap(&x);
cout << endl << x << endl;
system("pause");
return 0;
}
and
unsigned short int ByteSwap(unsigned short int *x)
{
long s;
long byte1[8], byte2[8];
for (int i = 0; i < 16; i++)
{
s = (*x >> i)%2;
if(i < 8)
{
byte1[i] = s;
cout << byte1[i];
}
if(i == 8)
cout << " ";
if(i >= 8)
{
byte2[i-8] = s;
cout << byte2[i];
}
}
//Here I need to swap the two bytes
return *x;
}
My code has two problems I am hoping you can help me solve.
For some reason both of my bytes are 01000000
I really am not sure how I would swap the bytes. My teachers notes on bit manipulation are very broken and hard to follow and do not make much sense me.
Thank you very much in advance. I truly appreciate you helping me.
New in C++23:
The standard library now has a function that provides exactly this facility:
#include <iostream>
#include <bit>
int main() {
unsigned short x = 258;
x = std::byteswap(x);
std::cout << x << endl;
}
Original Answer:
I think you're overcomplicating it, if we assume a short consists of 2 bytes (16 bits), all you need
to do is
extract the high byte hibyte = (x & 0xff00) >> 8;
extract the low byte lobyte = (x & 0xff);
combine them in the reverse order x = lobyte << 8 | hibyte;
It looks like you are trying to swap them a single bit at a time. That's a bit... crazy. What you need to do is isolate the 2 bytes and then just do some shifting. Let's break it down:
uint16_t x = 258;
uint16_t hi = (x & 0xff00); // isolate the upper byte with the AND operator
uint16_t lo = (x & 0xff); // isolate the lower byte with the AND operator
Now you just need to recombine them in the opposite order:
uint16_t y = (lo << 8); // shift the lower byte to the high position and assign it to y
y |= (hi >> 8); // OR in the upper half, into the low position
Of course this can be done in less steps. For example:
uint16_t y = (lo << 8) | (hi >> 8);
Or to swap without using any temporary variables:
uint16_t y = ((x & 0xff) << 8) | ((x & 0xff00) >> 8);
You're making hard work of that.
You only neeed exchange the bytes. So work out how to extract the two byte values, then how to re-assemble them the other way around
(homework so no full answer given)
EDIT: Not sure why I bothered :) Usefulness of an answer to a homework question is measured by how much the OP (and maybe other readers) learn, which isn't maximized by giving the answer to the homewortk question directly...
Here is an unrolled example to demonstrate byte by byte:
unsigned int swap_bytes(unsigned int original_value)
{
unsigned int new_value = 0; // Start with a known value.
unsigned int byte; // Temporary variable.
// Copy the lowest order byte from the original to
// the new value:
byte = original_value & 0xFF; // Keep only the lowest byte from original value.
new_value = new_value * 0x100; // Shift one byte left to make room for a new byte.
new_value |= byte; // Put the byte, from original, into new value.
// For the next byte, shift the original value by one byte
// and repeat the process:
original_value = original_value >> 8; // 8 bits per byte.
byte = original_value & 0xFF; // Keep only the lowest byte from original value.
new_value = new_value * 0x100; // Shift one byte left to make room for a new byte.
new_value |= byte; // Put the byte, from original, into new value.
//...
return new_value;
}
Ugly implementation of Jerry's suggestion to treat the short as an array of two bytes:
#include <iostream>
typedef union mini
{
unsigned char b[2];
short s;
} micro;
int main()
{
micro x;
x.s = 258;
unsigned char tmp = x.b[0];
x.b[0] = x.b[1];
x.b[1] = tmp;
std::cout << x.s << std::endl;
}
Using library functions, the following code may be useful (in a non-homework context):
unsigned long swap_bytes_with_value_size(unsigned long value, unsigned int value_size) {
switch (value_size) {
case sizeof(char):
return value;
case sizeof(short):
return _byteswap_ushort(static_cast<unsigned short>(value));
case sizeof(int):
return _byteswap_ulong(value);
case sizeof(long long):
return static_cast<unsigned long>(_byteswap_uint64(value));
default:
printf("Invalid value size");
return 0;
}
}
The byte swapping functions are defined in stdlib.h at least when using the MinGW toolchain.
#include <stdio.h>
int main()
{
unsigned short a = 258;
a = (a>>8)|((a&0xff)<<8);
printf("%d",a);
}
While you can do this with bit manipulation, you can also do without, if you prefer. Either way, you shouldn't need any loops though. To do it without bit manipulation, you'd view the short as an array of two chars, and swap the two chars, in roughly the same way as you would swap two items while (for example) sorting an array.
To do it with bit manipulation, the swapped version is basically the lower byte shifted left 8 bits ord with the upper half shifted left 8 bits. You'll probably want to treat it as an unsigned type though, to ensure the upper half doesn't get filled with one bits when you do the right shift.
This should also work for you.
#include <iostream>
int main() {
unsigned int i = 0xCCFF;
std::cout << std::hex << i << std::endl;
i = ( ((i<<8) & 0xFFFF) | ((i >>8) & 0xFFFF)); // swaps the bytes
std::cout << std::hex << i << std::endl;
}
A bit old fashioned, but still a good bit of fun.
XOR swap: ( see How does XOR variable swapping work? )
#include <iostream>
#include <stdint.h>
int main()
{
uint16_t x = 0x1234;
uint8_t *a = reinterpret_cast<uint8_t*>(&x);
std::cout << std::hex << x << std::endl;
*(a+0) ^= *(a+1) ^= *(a+0) ^= *(a+1);
std::cout << std::hex << x << std::endl;
}
This is a problem:
byte2[i-8] = s;
cout << byte2[i];//<--should be i-8 as well
This is causing a buffer overrun.
However, that's not a great way to do it. Look into the bit shift operators << and >>.