I am trying to convert unsigned char in C to matlab code, the vector of unsigned char is filled with hexadecimal values. Below the C code:
int main()
{
unsigned char value = 0xaa;
signed char temp;
// cast to signed value
temp = (signed char) value;
// if MSB is 1, then this will signed extend and fill the temp variable with 1's
temp = temp >> 7;
// AND with the reduction variable
temp = temp & 0x1b;
// finally shift and reduce the value
printf("%u",((value << 1)^temp));
}
The Matlab function that I create to do the same thing:
value = '0xaa';
temp = int8(value);
temp2 = int8(value);
temp = bitsra(temp,7);
temp = and(temp,'0x1b');
galois_value = xor(bitsll(temp2,1),temp);
disp(galois_value);
The values printed are different in each code, someone knows what is happening?
You have created a string:
value = '0xaa';
Of 4 characters, ['0' 'x' 'a' 'a'].
In MATLAB you don't generally handle variables bit wise, but if you want, try:
temp = int8(hex2dec('aa'));
Related
I wrote the following function. This function receives the address of a hex value e.g. 0x4571 and calculates with Day, Month and Year from the bit positions of the hex value.
void fat_dir_date(char *dateAr) {
const unsigned int MaskDayOfMonth = 0x1F; //0000000000011111
const unsigned int MaskMonthOfYear = 0x1E0; //0000000111100000
const unsigned int MaskYear = 0xFE00; //1111111000000000
unsigned int DayOfMonth = hex & MaskDayOfMonth; //AND Bit Operation
unsigned int MonthOfYear = hex & MaskMonthOfYear; //AND Bit Operation
MonthOfYear = MonthOfYear >> 5; //Bitshift to right position
unsigned int Year = hex & MaskYear; //AND Bit Operation
Year = Year >> 9; //Bitshift to right position
printf("%d.%d.%d", DayOfMonth, MonthOfYear, 1980+Year);
}
The calculation works fine. I get the right numbers in the integer DayOfMonth,MonthOfYear and Year. But instead of printing them out with printf, I want to return the values to the caller function. In the best way in concatenated in a single value or string.
How is the best way to solve this in C?
You have several options there:
Create a struct that has the three fields, and return it,
Let the caller pass you the struct that you fill in,
Let the caller pass you a string buffer to which you print using sprintf, or
Create a string dynamically, print to it, and return.
The first option is clean and easy to understand. It requires some copying, but it is fine for small structures like the one that you need:
struct DateTime {
int DayOfMonth;
int MonthOfYear;
int Year;
};
struct DateTime fat_dir_date(unsigned int hex) {
struct DateTime res;
res.DayOfMonth = ...
res.MonthOfYear = ...
res.Year = ...
return res;
}
If you need to print the data and you don't need to use the numeric values, I think this:
char * fat_dir_date(char *dateAr,unsigned int hex) {
const unsigned int MaskDayOfMonth = 0x1F; //0000000000011111
const unsigned int MaskMonthOfYear = 0x1E0; //0000000111100000
const unsigned int MaskYear = 0xFE00; //1111111000000000
unsigned int DayOfMonth = hex & MaskDayOfMonth; //AND Bit Operation
unsigned int MonthOfYear = hex & MaskMonthOfYear; //AND Bit Operation
MonthOfYear = MonthOfYear >> 5; //Bitshift to right position
unsigned int Year = hex & MaskYear; //AND Bit Operation
Year = Year >> 9; //Bitshift to right position
sprintf(dateAr,"%02u.%02u.%4u", DayOfMonth,MonthOfYear, 1980+Year);
return dateAr;
}
int main(void)
{
char dateAr[11];
unsigned int hex=0x1010; //Random :)
printf("%s\n" , fat_dir_date(dateAr,hex))
return 0;
}
while reading the book Computer System a programmer perspective.I have found that if i take most negative value in the range of a data type for example :
char a = -128;
a = - a;
The variable a will still have the value -128 and i understand that but when i do
char a = 50;
char b = -128;
char r = a - b;
It give me the correct result -78, why is that?? it because the automatic promotion to int or there is a hardware subtraction without needing to calculate two complement of -128??
char a = -128; means char a = 0x80;, so at the promotion to int it will be 0xFFFFFF80.
-0xFFFFFF80 = 0x00000080 and that is casted to an char 0x80 which is the same as the start value.
char a = -128;
char b = 50;
char r = a - b;
0xFFFFFF80
0xFFFFFFCE
=
0xFFFFFF4E
so 4E will be written in r, which is +78.
live demo: https://ideone.com/sjyBOa
I have code snippet as Below
unsigned char p = 0;
unsigned char t[4] = {'a','b','c','d'};
unsigned int m = 0;
for(p=0;p<4;p++)
{
m |= t[p];
printf("%c",m);
m = m << 2;
}
Can anybody help me in solving this. consider i have an ascii value abcd stored in an array t[]. I want to store the same value in 'm'. m is my unsigned int variable . which stores the major number. when i copy the array into m & print m . m should print abcd. can anybody state their logic.
As I understand you, you want to encode the 4 characters into a single int.
Your bit shifting is not correct. You need to shift by 8 bits rather than 2. You also need to perform the shifting before the bitwise or. Otherwise you shift too far.
And it makes more sense, in my view, to print the character rather than m.
#include <stdio.h>
int main(void)
{
const unsigned char t[4] = {'a','b','c','d'};
unsigned int m = 0;
for(int p=0;p<4;p++)
{
m = (m << 8) | t[p];
printf("%c", t[p]);
}
printf("\n%x", m);
return 0;
}
Why not just look at the t array as an unsigned int?:
unsigned int m = *(unsigned int*)t;
Or you could use an union for nice access to the same memory block in two different ways, which I think is better than shifting bits manually.
Below is an union example. With unions, both the t char array and the unsigned int are stored in the same memory blob. You get a nice interface to each, and it lets the compiler do the bit shifting (more portable, I guess):
#include <stdio.h>
typedef union {
unsigned char t[4];
unsigned int m;
} blob;
int main()
{
blob b;
b.t[0]='a';
b.t[1]='b';
b.t[2]='c';
b.t[3]='d';
unsigned int m=b.m; /* m holds the value of blob b */
printf("%u\n",m); /* this is the t array looked at as if it were an unsignd int */
unsigned int n=m; /* copy the unsigned int to another one */
blob c;
c.m=n; /* copy that to a different blob */
int i;
for(i=0;i<4;i++)
printf("%c\n",c.t[i]); /* even after copying it as an int, you can still look at it as a char array, if you put it into the blob union -- no manual bit manipulation*/
printf("%lu\n", sizeof(c)); /* the blob has the bytesize of an int */
return 0;
}
Simply assign t[p] to m.
m = t[p];
this will implicitly promote char to unsigned int.
unsigned char p = 0;
unsigned char t[4] = {'a','b','c','d'};
unsigned int m = 0;
for(p=0;p<4;p++)
{
m = t[p];
printf("%c",m);
}
I have a string x that I need to convert into a hex format:
char x[5];
x[0]='0';
x[1]='1';
x[2]='0';
x[3]='1'; //x contains value of 0xA or decimal 10;
x[4]='\0';
Now how can I convert this and store it into an unsigned integer variable so the variable would be of value 0xA;
Thanks.
It seems that the number is stored in reversed direction, which is not natural for human to read, but quite a natural way to represent number as the index refers to the power of 2 that should be applied.
There is no existing library to do the conversion for you, you need to write code to parse it yourself:
int i = 0;
unsigned int result = 0;
while (x[i]) {
result |= (x[i] == '1') << i;
i++;
}
Why is the string in x in reversed order?
char x[5] = {'1', '0', '1', '0' };
unsigned int result = 0;
int i = 0;
while(x[i] != 0)
{
result = result * 2 + x[i]-'0';
}
char *x = "0101";
Does not equal 0xA or decimal 10. Binary '1010' would, maybe that's what you meant?
Simple way to convert string-represented numbers is strtol, among many other functions like atoi. strtol at least allows a radix to be supplied.
http://www.cplusplus.com/reference/clibrary/cstdlib/strtol
Something like:
unsigned long val = strtol(x, NULL, 2);
Will the statement below calculate the length of the array???:
UART1_BUF[1] = (unsigned char)(lcl_ptr - (unsigned char *)&UART1_BUF[1]);
/////////////////////////////////////////////////////////////////////////////////////
unsigned char UART1_BUF[128];
void apple_Build_SetFIDTokenValues(void)
/* apple_Build_SetFIDTokenValues -
*
* This function builds the apple protocol StartIDPS() command.
*/
{
unsigned char * lcl_ptr;
UART1_BUF[0] = BT_START_OF_PACKET;
UART1_BUF[1] = 0x00;
//BundleSeedIDPrefToken
lcl_ptr = apple_Build_BundleSeedIDPrefToken(&UART1_BUF[1]);
UART1_BUF[1] = (unsigned char)(lcl_ptr - (unsigned char *)&UART1_BUF[1]);
*lcl_ptr = apple_checksum((unsigned char *)UART1_BUF, UART1_BUF[1]);
UART1_BUF[UART1_BUF[1]] = *lcl_ptr;
}
unsigned char * apple_Build_BundleSeedIDPrefToken(unsigned char *buf_ptr)
{
*(buf_ptr++) = 0x0D; //length of BundleSeedIDPrefToken minus this byte
*(buf_ptr++) = BundleSeedIDPref_Token_FID_TYPE;
*(buf_ptr++) = BundleSeedIDPref_Token_FID_SUBTYPE;
//BundleSeedIDString
*(buf_ptr++) = '0';
*(buf_ptr++) = '0';
*(buf_ptr++) = '0';
*(buf_ptr++) = '0';
*(buf_ptr++) = '0';
*(buf_ptr++) = '0';
*(buf_ptr++) = '0';
*(buf_ptr++) = '0';
*(buf_ptr++) = '0';
*(buf_ptr++) = '0';
*(buf_ptr++) = '0';
return (buf_ptr);
}
Yes, provided that the result fits in a byte - which, from the code sample, it will - and, by 'length of the array', you mean the number of bytes minus the packet header.
It will give you the number of bytes added by the apple_Build_BundleSeedIDPrefToken() function. (The total number of bytes that have been filled in the UART_BUF[] array is one more than that, because that statement won't count the byte at UART_BUF[0].)
In general, subtracting two pointers of type T * into an array of elements of type T gives you the difference as the number of elements (rather than the number of bytes). (The result is undefined if either of the two pointers do not point to either an element within the same array, or the element just past the last one.) The result itself has a signed integer type, ptrdiff_t, which is defined in <stddef.h>.
However, here, both pointers are pointing into the same array of unsigned char, so each element is a byte by definition.
So, the expression lcl_ptr - (unsigned char *)&UART1_BUF[1] will give the number of bytes added by the function. (Note that &UART_BUF[1] is of type unsigned char * already, so the cast inside the expression is unnecessary.)
That expression is then cast to unsigned char, which could in theory truncate the result, although it clearly doesn't in the above example.
I note that the code is a little odd, in that it assigns to UART_BUF[1] three times!
UART1_BUF[1] = 0x00; sets it to 0;
lcl_ptr = apple_Build_BundleSeedIDPrefToken(&UART1_BUF[1]); sets it to 0x0D inside the called function;
UART1_BUF[1] = (unsigned char)(lcl_ptr - (unsigned char *)&UART1_BUF[1]); sets it to 0x0E, as the function adds 14 bytes.
More generally, remember to be careful with pointer subtractions: expecting them to always give a number of bytes is a common mistake...
#include <stdio.h>
#include <stddef.h>
int main(void)
{
int array[4];
int *start, *end;
start = &array[1];
end = &array[3];
printf("Difference (as int *): %d\n", end - start);
printf("Difference (as char *): %d\n", (char *)end - (char *)start);
return 0;
}
gives (on a system where sizeof(int)==4):
Difference (as int *): 2
Difference (as char *): 8