Reputation: 5422
Say we have 8 bytes saved in an array like:
char array[8];
All of them are set to zero:
for (i = 0; i < 7; i++){
array[i] = 0x00;
}
How can shift a 1
from the first LSBit until the last MSBit like
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x01
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x02
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x04
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x08
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x10
.....................................
to
0x08 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x10 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x20 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x80 0x00 0x00 0x00 0x00 0x00 0x00 0x00
Here is what I've tried but the result isn't what I'm looking for:
uint8_t buffer[8];
int index = 0 ;
for ( index = 0; index < 8; index++){
buffer[index] = 0x00;
}
*buffer= 0x01;
for( index = 0 ; index < 64; index++){
*buffer = *buffer<< 1 ;
}
UPDATE
Here is an example of what I get:
#include <stdio.h>
int main (){
char buffer[2]={0x01, 0x00};
int i ;
for( i = 0 ; i < 12 ; i++){
printf("0x %2X %x \n",buffer[0], buffer[1]);
*buffer <<= 1;
}
}
And the output is:
0x 1 0
0x 2 0
0x 4 0
0x 8 0
0x 10 0
0x 20 0
0x 40 0
0x FFFFFF80 0
0x 0 0
0x 0 0
0x 0 0
0x 0 0
I really don't understand the 0xFFFFFF80!
Upvotes: 1
Views: 3890
Reputation: 5422
So I've done it , maybe it's not the best way but it works, and if someone needs I'll be glade to share it :
#include <stdio.h>
#include <stdint.h>
int main (){
uint8_t buffer[8];
char* pChar = buffer;
uint8_t carry =0x01;
int i = 0;
short lock [8];
// Array initialization
for ( i =0 ; i <8; i++){
buffer[i] =0x00;
lock[i] = 0x00;
}
pChar =buffer;
for( i = 0 ; i < 64 ; i++){
*pChar = carry;
printf(" 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x \n",buffer[0], buffer[1],buffer[2],buffer[3], buffer[4], buffer[5], buffer[6], buffer[7]);
carry<<=1;
if( i>=7 && lock[0]==0){
*pChar = 0;
pChar++;
carry=0x01;
lock[0]=1;
}else if ( i>=15 && lock[1]==0) {
*pChar = 0;
pChar++;
carry=0x01;
lock[1]=1;
}else if( i>= 23 && lock[2]==0){
*pChar =0;
pChar++;
carry=0x01;
lock[2] =1;
}
else if( i>= 31 && lock[3]==0){
*pChar =0;
pChar++;
carry=0x01;
lock[3] =1;
}
else if( i>=39 && lock[4]==0){
*pChar =0;
pChar++;
carry=0x01;
lock[4] =1;
}
else if( i>= 47 && lock[5]==0){
*pChar =0;
pChar++;
carry=0x01;
lock[5] =1;
}
else if( i>= 55 && lock[6]==0){
*pChar =0;
pChar++;
carry=0x01;
lock[6] =1;
}
}
thanks for your help !
Upvotes: 0
Reputation: 213809
What byte that is "LS byte" and which one that is "MS byte" is perhaps not obvious. An array of 8 characters is always allocated in memory like this:
LS address MS address
Byte 0, ... Byte 7
This is true for all CPUs. So the 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x01
in your question doesn't make any sense: you have misunderstood how arrays are allocated in memory. What you have shown in your examples is how to take bit 0 in the ms byte and left shift it to bit 7 in the ls byte. Which probably doesn't make any sense.
However, if you would attempt to print this array as a 64 bit integer, the value array[0]=1
would give you 0000000000000001
on a little endian machine, but 0100000000000000
on a big endian machine. But nothing in your question states that you want to print the array as a 64 bit value, so it is not clear what you are actually asking.
Try this:
#include <stdio.h>
#include <stdint.h>
typedef union
{
uint8_t array[8];
uint64_t u64;
} my_type;
int main()
{
my_type t = {0};
t.array[0] = 0x01;
// how the array is actually allocated:
for(int i=0; i<8; i++) // 0100000000000000 on all machines
{
printf("%.2X", t.array[i]);
}
printf("\n");
// how the array turns out when printed as a 64 bit int:
printf("%.16llX\n", t.u64); // 0000000000000001 little endian
// perhaps what you intended to do, on a little endian machine
t.u64 <<= 63;
printf("%.16llX\n", t.u64); // 8000000000000000 little endian
return 0;
}
Upvotes: 3
Reputation: 2670
Since you are trying to treat your char array as a single 64 bit object, why not use an actual 64 bit object?
union
{
char array[8];
uint64_t all;
} data;
int index = 0;
data.all = 0;
data.array[0] = 0x01;
for(index = 0; index < 64; index++)
{
data.all = data.all << 1;
}
Note that this assumes that you are working on a little endian machine.
Upvotes: 0
Reputation: 100622
As per harold's comment, just carry the 1. So, to shift one place:
uint8_t carry = 0;
for( index = 7 ; index >= 0; index--){
uint8_t nextCarry = buffer[index] >> 7;
buffer[index] = (buffer[index] << 1) | carry;
carry = nextCarry;
}
EDIT: also, it strikes me that your CPU almost certainly has a native 64-bit type. In which case just use a uint64_t
directly rather than an array of bytes and perform variable <<= 1;
.
Upvotes: 2
Reputation: 118
I'm not sure if this is what you want, but the following code does at least what was posed in the question:
uint8_t temp = buffer[0];
printf("Initial Buffer :\n");
for(int i = 0 ; i < 8 ; i++)
printf("0x%X ", buffer[7-i]);
// Left Shift until highest bit that is 1 is found
while(!(temp & 0x80))
temp = temp<<1;
// Re-assignments
buffer[7] = temp;
buffer[0] = 0;
printf("\nFinal Buffer :\n");
for(int i = 0 ; i < 8 ; i++)
printf("0x%X ", buffer[7-i]);
In true sense, this is not "shifting entirely through the buffer", but if you could provide more details on what you wish to accomplish, this code could be modified accordingly.
Upvotes: 0