How to make specific bit manipulation? - c++

I'm doing practice of bit manipulation in arduino with a 74HC595 shift register.
I would like to create an algorithm that allows the binary digit to perform this way:
1 0 0 0 0 0 0 1
0 1 0 0 0 0 1 0
0 0 1 0 0 1 0 0
.
.
.
1 0 0 0 0 0 0 1
In this type of function the decimal values are: (129,66,36,24,24,36,66,129) and so on in a loop.
How can I perform this type of shifting? I don't have any fluency thinking this type of operation, I have only performed a circular shift with "an algorithm" like:
//my circular shift
myByte = myByte*128 + myByte/2
But I don't know how to perform the output that I showed.
How can I do this? Thanks

For example you can use the following approach
#include <iostream>
#include <iomanip>
#include <limits>
int main()
{
unsigned char b = 0b10000001;
int width = std::numeric_limits<unsigned char>::digits / 2;
for ( int i = 0; i < width; i++ )
{
std::cout << std::hex << static_cast<int>( b ) << " - "
<< std::dec << static_cast<int>( b ) << '\n';
b = ( b & ( 0b1111 << width ) ) >> 1 | ( b & 0b1111 ) << 1;
}
for ( int i = 0; i < width; i++ )
{
std::cout << std::hex << static_cast<int>( b ) << " - "
<< std::dec << static_cast<int>( b ) << '\n';
b = ( b & ( 0b1111 << width ) ) << 1 | ( b & 0b1111 ) >> 1;
}
return 0;
}
The program output is
81 - 129
42 - 66
24 - 36
18 - 24
18 - 24
24 - 36
42 - 66
81 - 129

You're looking for a single operation that can be applied to an 8 bit number and result in the given pattern.
You want
x_(n+1) = f(x_(n))
for all given inputs and outputs. The problem is that there are a few potential inputs that have one of two possible outputs. You want both
36 = f(66)
and
129 = f(66)
This can't be done using only one variable. You can either implement a lookup table for the sequence you want (which is what I suggest). Or you can take two variables, implement circular shifts (in opposite directions) on each, and take the bitwise OR of the results.
uint8_t n1 = 128, n2 = 1;
for(;;)
{
std::cout << n1 | n2 << "\n";
n1 = circular_right_shift(n1);
n2 = circular_left_shift(n2);
}

Noticing that:
129,66,36,24,24,36,66,129 = 128+1; 64+2 ; 32+4; 16+8; 16+8; 32+4; 64+2; 128+1;
I ended up with this code:
int latchPin = 11;
int clockPin = 9;
int dataPin = 12;
int dt = 2000;
uint8_t n1 = 128, n2 = 1;
byte myByte = 0b10000001; //in BIN
void setup() {
Serial.begin(9600);
pinMode(latchPin,OUTPUT);
pinMode(dataPin,OUTPUT);
pinMode(clockPin,OUTPUT);
}
//circular shift to the left
void loop() {
digitalWrite(latchPin,LOW);
shiftOut(dataPin,clockPin,LSBFIRST,myByte);
digitalWrite(latchPin,HIGH);
int i;
myByte = 0b10000001; //restarting the value of 129
Serial.print("BIN: ");
Serial.print(myByte,BIN);
Serial.print(" --> ");
Serial.print("HEX: ");
Serial.print(myByte,HEX);
Serial.print(" --> ");
Serial.print("DEC: ");
Serial.println(myByte,DEC);
delay(200);
for (int i = 0; i < 7; i++) {
Serial.print("i: ");
Serial.println(i);
//int i1 = i+1;
//int myGap = myByte - (pow(2,i)); //no need to round when it's raised to 0;
//int firstpart = (myGap/2);
//int secondpart = 0.5 + pow(2,i1); //because it rounds the number. (i.e --> 1.9999 = 1)
//myByte = firstpart+ secondpart;
myByte = (myByte - (pow(2,i)))/2 + (0.5 + pow(2,i+1));
//Serial.print("firstpart: ");
//Serial.println(firstpart);
//Serial.print("secondpart: ");
//Serial.println(secondpart);
//delay(3000);
Serial.print("BIN: ");
Serial.print(myByte,BIN);
Serial.print(" --> ");
Serial.print("HEX: ");
Serial.print(myByte,HEX);
Serial.print(" --> ");
Serial.print("DEC: ");
Serial.println(myByte,DEC);
digitalWrite(latchPin,LOW);
shiftOut(dataPin,clockPin,LSBFIRST,myByte);
digitalWrite(latchPin,HIGH);
delay(100);
}
//myByte = myByte*2; //shift by right //using MSBFIRTS
//delay(dt);
}
And it works.

Related

OpenCV data of two mats are the same but values when retrieved with Mat::at are corrupted

I serialize and then deserialize a Mat using custom functions. When you compare the uchar* Mat.data of two functions they are the same but when I try to check values directly using Mat.at<> after third element, element values are stuck at some corrupted float values. I tried changing elements to every other value, nothing changed. The problem also doesn't happen when I serialize-deserialize image Mats and histogram Mats. Below is the code and below that is the output.
cv::Mat kernelx = (cv::Mat_<float>(3, 3) << 1, 0, -1, 1, 0, -1, 1, 0, -1);
std::string stroper = dbop::serializeMat(kernelx);
cv::Mat matoper = dbop::deserializeMat(stroper);
for (int i = 0; i < matoper.rows; i++) {
for (int j = 0; j < matoper.cols; j++) {
float f1 = (float)kernelx.data[i + j];
float f2 = (float)matoper.data[i + j];
std::cout << kernelx.at<float>(i, j) << " " << matoper.at<float>(i, j) << " " << f1 << " " << f2 << " " << std::endl;
}
}
Here is the output. First values are elements of the original Mat, second values are elements of serialized-deserialized Mat, third values are the original Mat's data values casted to float, fourth values are s-d Mat's data values.
1 1 0 0
0 0 0 0
-1 -4.31596e+08 128 128
1 -4.31602e+08 0 0
0 -4.31602e+08 128 128
-1 -4.31602e+08 63 63
1 -4.31602e+08 128 128
0 -4.31602e+08 63 63
-1 -4.31602e+08 0 0
I guess serializeMat and deserializeMat functions are relevant here so here is both.
std::string dbop::serializeMat(cv::Mat operand) {
std::ostringstream srlzstrstream;
uchar* pixelPtr = (uchar*)operand.data;
int cn = operand.channels();
cv::Scalar_<uchar> cnPixel;
srlzstrstream << operand.dims << " ";
for (int i = 0; i < operand.dims; i++) {
srlzstrstream << operand.size[i] << " ";
}
srlzstrstream << operand.type() << " ";
for (int i = 0; i < operand.total(); i++) {
for (int k = 0; k < cn; k++) {
srlzstrstream << (float)pixelPtr[i * cn + k] << " ";
}
}
std::string srlzdstr = srlzstrstream.str();
return srlzdstr;
}
cv::Mat dbop::deserializeMat(std::string operand){
std::istringstream desrlzstrstream(operand);
int mdims, mtype;
desrlzstrstream >> mdims;
int* msize = new int[mdims];
for (int i = 0; i < mdims; i++)
desrlzstrstream >> msize[i];
desrlzstrstream >> mtype;
cv::Mat matoper(mdims, msize, mtype);
delete [] msize;
uchar* pixelPtr = (uchar*)matoper.data;
float cnpixoper;
for (int i = 0; i < matoper.total(); i++) {
for (int k = 0; k < matoper.channels(); k++) {
desrlzstrstream >> cnpixoper;
pixelPtr[i * matoper.channels() + k] = cnpixoper;
}
}
return matoper;
}
+ Edit
Since you want to save byte for generic types, you can just iterate each byte like this.
In serializeMat
for (int i = 0; i < operand.total() * operand.elemSize(); i++) {
srlzstrstream << pixelPtr[i] << " ";
}
In deserializeMat
for (int i = 0; i < matoper.total() * matoper.elemSize(); i++) {
desrlzstrstream >> cnpixoper;
pixelPtr[i] = cnpixoper;
}
operand.total() * operand.elemSize() will give you the byte size of operand
In both case, the output is
1 1 0 0
0 0 0 0
-1 -1 128 128
1 1 0 0
0 0 128 128
-1 -1 63 63
1 1 128 128
0 0 63 63
-1 -1 0 0

I have to change my number last digit and first digit but without using functions only with integers or loops. For example from 12345 to 52341

#include <iostream>
using namespace std;
int main()
{
// Here I seperate my number because at first I have to seperate and then I have to change the first digit and last digit.
int numri, shifrat, i = 0, a, shuma = 0, m, d;
cout << "Jep nje numer \n";
cin >> numri;
m = numri;
while (numri != 0) {
i++;
numri = numri / 10;
}
d = pow(10, i - 1);
numri = m;
while (numri != 0) {
shifrat = numri / d;
cout << shifrat << " ";
numri = numri % d;
d = d / 10;
}
//Now after that I have to change the last digit and first digit. Please help me.
//But I'm not allowed to use functions or swap only integers and loops or conditions.
cin.get();
}
Can someone help me please?
It is more about maths than anything else.
To get the last digit of an integer we can use modulo:
z = abc....xyz % 10
To "remove" that digit from the number we use
abc...xy = abc...xyz / 10
(where / denotes integer division, ie 34/10 == 3).
I think this is what you already know how to do. Instead of deep diving into code, you should have done the maths also for the missing part first.
To add a digit to an integer we do
abc...xyz = (abc...xy * 10) + z
Only now you have all pieces necessary to start writing code:
int main() {
int inp;
int outp = 0;
std::cin >> inp; // read_input
while(inp > 0) { // reverse
int digit = ... // get_digit
inp = ... // remove_digit
outp = ... // add_digit
}
std::cout << outp;
}
It is unfortunate that you are not allowed to use functions. One of the next lessons should be that functions are much better than comments in naming things and making your code explicit
int read_input();
int remove_digit(int x);
int add_digit(int x,int digit);
int reverse(int x);
int main() {
int inp = read_input();
std::cout << reverse(inp);
}
The program can be written without using the function pow.
Here you are.
#include <iostream>
int main()
{
while ( true )
{
std::cout << "Enter a non-negative number (0 - exit): ";
unsigned int n;
if ( not ( std::cin >> n ) or n == 0 ) break;
std::cout << '\n';
const unsigned int Base = 10;
unsigned int factor = 1;
while ( not ( n / factor < Base ) ) factor *= Base;
unsigned int last_digit = n / factor;
unsigned int first_digit = n % Base;
n %= factor;
n = n - first_digit + last_digit;
first_digit *= factor;
n = first_digit + n;
std::cout << n << "\n\n";
}
return 0;
}
The program output might look like
Enter a non-negative number (0 - exit): 987654321
187654329
Enter a non-negative number (0 - exit): 12345
52341
Enter a non-negative number (0 - exit): 100
1
Enter a non-negative number (0 - exit): 1
1
Enter a non-negative number (0 - exit): 0
If these statements
if ( not ( std::cin >> n ) or n == 0 ) break;
and
while ( not ( n / factor < Base ) ) factor *= Base;
contain symbols that you do not know yet then you can rewrite them like
if ( !( std::cin >> n ) || n == 0 ) break;
and
while ( !( n / factor < Base ) ) factor *= Base;
You can create a program with 4 variables - n, the given number, cn - the created number, u - the last digit of the given number and p - the 10^p number;
You will save the last n digit and create the 10^p number in while. Then, using the formula
cn = ((u * p + cn % p) /10) * 10 + n;
you will create the new number;
#include <iostream>
using namespace std;
int main() {
int n, cn, u, p;
cin>>n;
u = n % 10;
cn = n;
p = 1;
while(n>9) {
p = p * 10;
n = n / 10;
}
cn = ((u * p + cn % p) /10) * 10 + n;
cout<<cn;
return 0;
}
To exchange first and last digit in a number ABCDEF --> FBCDEA
num = 12345
res = 52341
the idea is that :
52341 = 12345 - 10005 + 50001
first digit fd = num % 10
decimal places multiplier df = 1
until num is not zero we do
last digit ld = num
num = num / 10
if num != 0 decimal places multiplier df = df*10
result = ABCDEF - F - A*100000 + A + F*100000
int m = numri;
int ld = 0; // last digit(most)
int fd = numri % 10; // first digit(least)
int df = 1; // last digit multiplier 10^n where n is decimal places
while (numri != 0) {
ld = numri;// this will be the last digit in last iteration
numri = numri / 10;
if(numri) df = df * 10;
}
int res = m - fd - ld * df + fd * df + ld;
cout<<res;
example:
if the num = 12345
fd = 12345 % 10 =5
df = 1
num = 12345 / 10 = 1234
df = df*10 = 10
num = 1234 / 10 = 123
df = df*10 = 100
num = 123 / 10 = 12
df = df*10 = 1000
fd = num = 12
num = 12 / 10 = 1
df = df*10 = 10000
fd = num = 1
num = 1/10 =0
df not changed
loop exit
result = 12345 - 5 - 1*10000 + 1 + 5*10000 = 62341

Trying to check for 3 of a kind with arrays (Yahtzee) C++

I am trying to check for if the kept dice rolls (which can be up to 5) are 3 of a kind or not, so I'm trying to compare the dice roll values to each other.
The first value of R is showing as 0 of course, but the second value of R after the code is run is showing as 8191 every time, and I'm not entirely sure why.
I've also tried using
r++ instead of r += r+1, but of course that didn't change anything.
int r = 0;
cout << "first value of R is " << r << endl;
for(int t = 0; t < 5; t++) {
for(int w = 0; w < 5; w++) {
if(keptDice[t] == keptDice[w] ) {
r += r + 1;
}
}
}
cout << "Value of R is " << r << endl;
The point is that in the second for loop yo have tor start from t (int w = t;...) otherwise you would compare each dice with itself which will be naturally equal. Plus use r++ instead of r += r + 1 which is definitely wrong but I think that is just a misspelling.
int r = 0;
cout << "first value of R is " << r << endl;
for(int t = 0; t < 5; t++) {
for(int w = t; w < 5; w++) {
if(keptDice[t] == keptDice[w] ) {
r++;
}
}
}
cout << "Value of R is " << r << endl;
r += r + 1
is the same as writing
r = r + r + 1
r is doubling every time. Interestingly, it's always 1 less than 2^n
r = 0 + 0 + 1 (1)
r = 1 + 1 + 1 (3)
r = 3 + 3 + 1 (7)
r = 7 + 7 + 1 (15)
r = 15 + 15 + 1 (31)
r = 31 + 31 + 1 (63)
r = 63 + 63 + 1 (127)
r = 127 + 127 + 1 (255)
r = 255 + 255 + 1 (511)
r = 511 + 511 + 1 (1023)
r = 1023 + 1023 + 1 (2047)
r = 2047 + 2047 + 1 (4095)
r = 4095 + 4095 + 1 (8191)
Your program is counting 13 matches. For yahtzee, you probably want an array that counts matches, otherwise you're doubling up on each die. For example, if you had
1 2 3 4 1
It would count the first 1 matching the last die AND the last die matching the first (2 matches).
What would be more sensible is to count how many 1's you have, how many 2s you have, and store in an array
int diceCount[6];
for(int num = 1; num <= 6; num++) {
for(int w = 0; w < 5; w++) {
int count = 0;
if(keptDice[w] == num ) {
count++;
}
diceCount[num-1] = count;
}
This way when it's done, if you had two 1's, then diceCount[0] will be 2
Based on your approach, but generalized to N-of-a-kind:
int N = 3; // N in [1;5]
bool isNOfAKind = false;
for(int t = 0; t < 6-N; t++) { // skip searches with less elements than N
int r = 0; // r must be reset for each count
for(int w = t+1; w < 5; w++) { // avoid comparing to self
if(keptDice[t] == keptDice[w]) {
r++;
}
}
// found a solution already? then bail out.
if(r == N) {
isNOfAKind = true;
break;
}
}
cout << N << " of a kind? " << isNOfAKind << endl;

feeding hex characters to stringstream

I'm trying to set bits in a binary string. I initially have an empty string which needs to set the give bit(i) in the string(s).
for the given example, the output should be 0x3001 as:
pos: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
bit: 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1
^ ^
MSB LSB
Which, in hex is 3001.
#include<iostream>
#include<string>
#include<sstream>
#include<iomanip>
using namespace std;
void generate_string(string& s,int i){
int sl = s.length();
int x = i/8;
std::stringstream m(s, ios_base::app);
if(sl<x){
for(int j = x-sl;j>=0;j--){
m<<'\x00';
}
}
s = m.str();
s[x] |= 1 << i%8;
}
int main(){
string s = "";
generate_string(s,15);
generate_string(s,2);
generate_string(s,3);
for(int i=0;i<s.length();i++)
cout<<hex<<(int)s[i];
return 0;
}
But this program is not showing any output.
It's actually much more simpler than you think. The only complicated part is to calculate the bit number to be set in the byte.
Oh, and why use a string for this? Why not a vector?
Here's my solution, using std::vector instead:
void set_bit(std::vector<uint8_t>& bits, unsigned bit)
{
static unsigned const bit_count = 8; // Should really use std::numeric_limits<uint8_t>::digits
unsigned index = bit / bit_count;
while (index + 1 > bits.size())
bits.push_back(0);
// Since the bit-numbers are reversed from what's "common",
// we need a little more complex calculation here.
// bit % bit_count to get the "normal" bit number
// bit_count - bit % bit_count to reverse the bit numbering
// Then -1 to get a number between 0 and 7
bits[index] |= 1 << (bit_count - bit % bit_count - 1);
}
You can use a similar solution using std::string too, but I don't see why.
Maybe like this?
#include<iostream>
#include<string>
using namespace std;
void set_bit(string& s,int i){
auto bits = ((i + 7) / 8) * 8;
if (bits > s.length())
{
auto diff = bits - s.length();
s += std::string(diff, '0');
}
s[i] = '1';
}
int main(){
string s;
set_bit(s, 2);
set_bit(s, 3);
set_bit(s, 15);
cout << s << endl;
return 0;
}
expected output:
0011000000000001
update: attempt 2 :-)
#include<iostream>
#include<iomanip>
#include<string>
using namespace std;
void set_bit(string& s,int i){
auto bytes = (i + 7) / 8;
if (bytes > s.length())
{
auto diff = bytes - s.length();
s += std::string(diff, 0);
}
s[i / 8] |= char(1 << (7-(i%8)));
}
int main(){
string s;
set_bit(s, 2);
set_bit(s, 3);
set_bit(s, 15);
std::cout << "as hex: ";
for (auto c : s) {
cout << hex << setfill('0') << setw(2) << (int(c) & 0xff);
}
cout << endl;
std::cout << "as binary: ";
auto sep = "";
for (auto c : s) {
unsigned char bits = c;
for (unsigned char mask = 0x80 ; mask ; mask >>= 1)
{
cout << sep << ((bits & mask) ? '1' : '0');
sep = " ";
}
}
cout << endl;
return 0;
}
expected output:
as hex: 3001
as binary: 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1
I don't quite understand what the output should be in Your problem, because You are mixing most/least signifanct bits with nibbles order in sample input/output, but I You would like to print number in hex as a string You can do sth like this:
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
void feed(std::string& s, int x){
unsigned int mask = 15;
int nibblesInWord = sizeof(void*)*16;
std::stringstream ss;
while(nibblesInWord--){
std::cout << int(x & mask) <<std::endl;
ss << int(x & mask);
x >>= 4;
}
s = ss.str();
std::reverse(s.begin(), s.end());
}
int main(){
std::string s;
feed(s, 99);
std::cout << s <<std::endl;
}

my bit level add function always sets the first bit to 0

I'm trying to build bit level addition for my emulator
It works for the most part, but the first bit of my accumulator register always gets set to 0, and I can't figure out why?
int main()
{
MCS6502 processor;
char mem1 = 0b00000001;
char mem2 = 0b00000001;
char mem3 = 0b00000000;
processor.LDA(mem1); //loads memory into accumulator
processor.ADC(mem2); //adds the inputed address to the accumulator
processor.STA(mem3); //stores the accumulator in memory
std::cout << +mem3 << std::endl;
return 0;
}
void MCS6502::LDA(const char &address)
{
registers[0] = address; //loads Accumulator
}
void MCS6502::STA(char &address)
{
address = registers[0]; //stores Accumulator
}
void MCS6502::ADC(const char &address)
{
char carry = 0b00000000;
if (flags[0] == true)
{
carry = 0b00000001;
}
char accumulator_bit_array[7];
char address_bit_array[7];
char result_bit_array[7];
ByteToBitArray(accumulator_bit_array, registers[0]);
std::cout << "accum bit after the function has ran " << +accumulator_bit_array[0] << std::endl;
ByteToBitArray(address_bit_array, address);
std::cout << "address bit after the function has ran " << +address_bit_array[0] << std::endl;
int i = 0;
while (i < 8)
{
std::cout << "counter "<< i << std::endl;
std::cout << "Accumulator bit in = " << +accumulator_bit_array[i] << std::endl;
std::cout << "Address bit in = " << +address_bit_array[i] << std::endl;
result_bit_array[i] = BitwiseAdd(accumulator_bit_array[i], address_bit_array[i], carry);
std::cout << "Bitwise Add restult = " << +result_bit_array[i] << std::endl;
i++;
}
registers[0] = BitArrayToByte(result_bit_array);
if (carry == 0b00000001)
{
flags[0] = true;
}
if (carry == 0b00000000)
{
flags[0] = false;
}
}
char BitwiseAdd(const char &bit1, const char &bit2, char &carry)
{
char xor_ = bit1 ^ bit2;
char ret = carry ^ xor_;
carry = (carry & xor_) | (bit1 & bit2);
return ret;
}
void ByteToBitArray(char bit_array[], const char &byte)
{
std::cout << "Byte inside array function before conversion " << +byte << std::endl;
bit_array[0] = byte & 0b00000001;
bit_array[1] = byte & 0b00000010;
bit_array[2] = byte & 0b00000100;
bit_array[3] = byte & 0b00001000;
bit_array[4] = byte & 0b00010000;
bit_array[5] = byte & 0b00100000;
bit_array[6] = byte & 0b01000000;
bit_array[7] = byte & 0b10000000;
bit_array[1] = bit_array[1] >> 1;
bit_array[2] = bit_array[2] >> 2;
bit_array[3] = bit_array[3] >> 3;
bit_array[4] = bit_array[4] >> 4;
bit_array[5] = bit_array[5] >> 5;
bit_array[6] = bit_array[6] >> 6;
bit_array[7] = bit_array[7] >> 7;
std::cout << "Bit inside array function after conversion " << +bit_array[0] << std::endl;
}
char BitArrayToByte(char bit_array[])
{
char byte = 0b00000000;
bit_array[1] = bit_array[1] << 1;
bit_array[2] = bit_array[2] << 2;
bit_array[3] = bit_array[3] << 3;
bit_array[4] = bit_array[4] << 4;
bit_array[5] = bit_array[5] << 5;
bit_array[6] = bit_array[6] << 6;
bit_array[7] = bit_array[7] << 7;
int i = 0;
while (i < 8)
{
byte = byte | bit_array[i];
i++;
}
return byte;
}
My output when I run this is:
Byte inside array function before conversion 1
Bit inside array function after conversion 1
accum bit after the function has ran 1
Byte inside array function before conversion 1
Bit inside array function after conversion 1
address bit after the function has ran 1
counter 0
Accumulator bit in = 0
Address bit in = 1
Bitwise Add restult = 1
counter 1
Accumulator bit in = 0
Address bit in = 0
Bitwise Add restult = 0
counter 2
Accumulator bit in = 0
Address bit in = 0
Bitwise Add restult = 0
counter 3
Accumulator bit in = 0
Address bit in = 0
Bitwise Add restult = 0
counter 4
Accumulator bit in = 0
Address bit in = 0
Bitwise Add restult = 0
counter 5
Accumulator bit in = 0
Address bit in = 0
Bitwise Add restult = 0
counter 6
Accumulator bit in = 0
Address bit in = 0
Bitwise Add restult = 0
counter 7
Accumulator bit in = 0
Address bit in = 0
Bitwise Add restult = 0
1
It should be 2, and I can't figure out why it doesn't work.
Your 3 arrays in ADC have 7 elements in them but the functions you pass them to expect 8. This results in undefined behavior, which is showing here as overwriting the first byte of the next array.