how to increment/decrement Hexadecimal value in C - c

I'm trying to create a counter using hex, I know this can easily be done using decimals, but is it possible to do this in hex, or is it the same in dec?
will it go like this?
myhex = 0x00;
myhex++;
or will it be done on an entirely different manner?
If you are asking why hex its because this is for an MCU and for me the best way to control the IO of MCU is using hex.

Yes if you try it you will see it, that it makes no difference if the number is hex, octal or decimal!
As an example:
#include <stdio.h>
int main() {
int myhex = 0x07;
int myOct = 07;
int myDec = 7;
printf("Before increment:\n");
printf("Hex: %x\n", myhex);
printf("Oct: %o\n", myOct);
printf("Dec: %d\n", myDec);
myhex++;
myOct++;
myDec++;
printf("After increment:\n");
printf("Hex: %x\n", myhex);
printf("Oct: %o\n", myOct);
printf("Dec: %d\n", myDec);
return 0;
}
Output:
Before increment:
Hex: 7
Oct: 7
Dec: 7
After increment:
Hex: 8
Oct: 10
Dec: 8

Related

fread seems to be reading the file from right to left

I have to read information from a bin file (they're 100k 6 bytes ethernet directions). I opened it with an editor and this is what is inside:
so using the code:
FILE *ptr;
ptr = fopen("ethdirs.bin", "r");
if (!ptr){
printf("Unable to open file");
}
uint64_t test;
fread(&test, 6, 1, ptr);
printf("result = %lx \n", test);
fread(&test, 6, 1, ptr);
printf("result = %lx \n", test);
fclose(ptr);
should print 1B26B354A1CF which is the first 6 bytes direction. However, it prints:
result = cfa154b3261b
which is exactly the direction I expect but read from right to left! Why is this happening and how should I solve it?
You got bit by endianness issues. Ethernet is big endian but your CPU is little endian.
Unfortunately there's no builtin to convert six bytes, so you have to do it yourself.
uint64_t test;
unsigned char convert[6];
fread(convert, 6, 1, ptr);
test =
((uint64_t)convert[0] << 40) |
((uint64_t)convert[1] << 32) |
((uint64_t)convert[2] << 24) |
((uint64_t)convert[3] << 16) |
((uint64_t)convert[4] << 8) |
((uint64_t)convert[5]);
Somebody might be able to figure out a faster bitbash, but you probably don't care.
Alternatively (depending on what you are doing) you could just print it in the endian you want like so:
unsigned char convert[6];
fread(convert, 6, 1, ptr);
//...
printf("%02X:%02X:%02X:%02X:%02X:%02X\n", convert[0], convert[1], convert[2], convert[3], convert[4], convert[5]);
I took the liberty of inserting the expected : separators in MAC addresses this time.

How to read binary inputs from a file in C

What I need to do is to read binary inputs from a file. The inputs are for example (binary dump),
00000000 00001010 00000100 00000001 10000101 00000001 00101100 00001000 00111000 00000011 10010011 00000101
What I did is,
char* filename = vargs[1];
BYTE buffer;
FILE *file_ptr = fopen(filename,"rb");
fseek(file_ptr, 0, SEEK_END);
size_t file_length = ftell(file_ptr);
rewind(file_ptr);
for (int i = 0; i < file_length; i++)
{
fread(&buffer, 1, 1, file_ptr); // read 1 byte
printf("%d ", (int)buffer);
}
But the problem here is that, I need to divide those binary inputs in some ways so that I can use it as a command (e.g. 101 in the input is to add two numbers)
But when I run the program with the code I wrote, this provides me an output like:
0 0 10 4 1 133 1 44 8 56 3 147 6
which shows in ASCII numbers.
How can I read the inputs as binary numbers, not ASCII numbers?
The inputs should be used in this way:
0 # Padding for the whole file!
0000|0000 # Function 0 with 0 arguments
00000101|00|000|01|000 # MOVE the value 5 to register 0 (000 is MOV function)
00000011|00|001|01|000 # MOVE the value 3 to register 1
000|01|001|01|100 # ADD registers 0 and 1 (100 is ADD function)
000|01|0000011|10|000 # MOVE register 0 to 0x03
0000011|10|010 # POP the value at 0x03
011 # Return from the function
00000110 # 6 instructions in this function
I am trying to implement some sort of like assembly language commands
Can someone please help me out with this problem?
Thanks!
You need to understand the difference between data and its representation. You are correctly reading the data in binary. When you print the data, printf() gives the decimal representation of the binary data. Note that 00001010 in binary is the same as 10 in decimal and 00000100 in binary is 4 in decimal. If you convert each sequence of bits into its decimal value, you will see that the output is exactly correct. You seem to be confusing the representation of the data as it is output with how the data is read and stored in memory. These are two different and distinct things.
The next step to solve your problem is to learn about bitwise operators: |, &, ~, >>, and <<. Then use the appropriate combination of operators to extract the data you need from the stream of bits.
The format you use is not divisible by a byte, so you need to read your bits into a circular buffer and parse it with a state machine.
Read "in binary" or "in text" is quite the same thing, the only thing that change is your interpretation of the data. In your exemple you are reading a byte, and you are printing the decimal value of that byte. But you want to print the bit of that char, to do that you just need to use binary operator of C.
For example:
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <limits.h>
struct binary_circle_buffer {
size_t i;
unsigned char buffer;
};
bool read_bit(struct binary_circle_buffer *bcn, FILE *file, bool *bit) {
if (bcn->i == CHAR_BIT) {
size_t ret = fread(&bcn->buffer, sizeof bcn->buffer, 1, file);
if (!ret) {
return false;
}
bcn->i = 0;
}
*bit = bcn->buffer & ((unsigned char)1 << bcn->i++); // maybe wrong order you should test yourself
// *bit = bcn->buffer & (((unsigned char)UCHAR_MAX / 2 + 1) >> bcn->i++);
return true;
}
int main(void)
{
struct binary_circle_buffer bcn = { .i = CHAR_BIT };
FILE *file = stdin; // replace by your file
bool bit;
size_t i = 0;
while (read_bit(&bcn, file, &bit)) {
// here you must code your state machine to parse instruction gl & hf
printf(bit ? "1" : "0");
if (++i >= 7) {
i = 0;
printf(" ");
}
}
}
Help you more would be difficult, you are basically asking help to code a virtual machine...

Save and restart random chain (drand48) from checkpoint in C

I'm trying to write a program that gives the same result either if is executed entirely or if is stopped and restarted from some checkpoint. To do that I need to be able to repeat exactly the same random number sequence in any scenario. So, here a piece of code where I tried to do that, but of course, I'm not successful. Could you help me to fix this code?
int main(){
int i;
long int seed;
// Initial seed
srand48(3);
// Print 5 random numbers
for(i=0;i<5;i++) printf("%d %f\n",i,drand48());
// CHECKPOINT: HOW TO PROPERLY SET seed?
seed=mrand48(); // <--- FIXME
// 5 numbers more
for(i=5;i<10;i++) printf("%d %f\n",i,drand48());
// Restart from the CHECKPOINT.
srand48(seed);
// Last 5 numbers again
for(i=5;i<10;i++) printf("%d %f\n",i,drand48());
}
If you need to be able to resume the random number sequence, you can't let the drand48() package hide the seed values from you, so you need to use different functions from the package. Specifically, you should be calling:
double erand48(unsigned short xsubi[3]);
instead of:
double drand48(void);
and you'll keep an array of 3 unsigned short values around, and at each checkpoint, you'll record their values as part of the state. If you need to resume where things left off, you'll restore the values from the saved state into your array, and then go on your merry way.
This is also how you write library code that neither interferes with other code using the random number generators nor is interfered with by other code using the random number generators.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
unsigned short seed[3] = { 0, 0, 3 };
// Print 5 random numbers
for (int i = 0; i < 5; i++)
printf("%d %f\n", i, erand48(seed));
// CHECKPOINT
unsigned short saved[3];
memmove(saved, seed, sizeof(seed));
// 5 numbers more
for (int i = 5; i < 10; i++)
printf("%d %f\n", i, erand48(seed));
// Restart from the CHECKPOINT.
memmove(seed, saved, sizeof(seed));
// Last 5 numbers again
for (int i = 5; i < 10; i++)
printf("%d %f\n", i, erand48(seed));
return 0;
}
Example run:
0 0.700302
1 0.122979
2 0.346792
3 0.290702
4 0.617395
5 0.059760
6 0.783933
7 0.352009
8 0.734377
9 0.124767
5 0.059760
6 0.783933
7 0.352009
8 0.734377
9 0.124767
Clearly, how you set the seed array initially is entirely up to you. You can easily allow the user to specify the seed value, and report the seed you're using so that they can do so. You might use some elements from the PID or the time of day and the sub-seconds component as a default seed, for example. Or you could access a random number device such as /dev/urandom and obtain 6 bytes of random value from that to use as the seed.
How can I allow the user to specify the seed value using only a long int? In this approach, it seems that the user need to define 3 numbers but I would like to ask only 1 number (like a safe prime) in the input file.
You can take a single number and split it up in any way you choose. I have a program that takes option -s to print the random seed, -S to set the seed from a long, and that sometimes splits the long into 3 unsigned short values when using a random Gaussian distribution generator. I mostly work on 64-bit systems, so I simply split the long into three 16-bit components; the code also compiles safely under 32-bit systems but leaves the third number in the seed as 0. Like this:
case 'q':
qflag = true;
break;
case 'r':
check_range(optarg, &min, &max);
perturber = ptb_uniform;
break;
case 's':
sflag = true;
break;
case 't':
delim = optarg;
break;
case 'S':
seed = strtol(optarg, 0, 0);
break;
case 'V':
err_version("PERTURB", &"#(#)$Revision: 1.6 $ ($Date: 2015/08/06 05:05:21 $)"[4]);
/*NOTREACHED*/
default:
err_usage(usestr);
/*NOTREACHED*/
}
}
if (sflag)
printf("Seed: %ld\n", seed);
if (gflag)
{
unsigned short g_seed[3] = { 0, 0, 0 };
g_seed[0] = (unsigned short)(seed & 0xFFFF);
g_seed[2] = (unsigned short)((seed >> 16) & 0xFFFF);
if (sizeof(seed) > 4)
{
/* Avoid 32-bit right shift on 32-bit platform */
g_seed[1] = (unsigned short)(((seed >> 31) >> 1) & 0xFFFF);
}
gaussian_init(&g_control, g_seed);
}
else
srand48(seed);
filter_anon(argc, argv, optind, perturb);
return 0;
}
For my purposes, it is OK (not ideal, but OK) to have the even more restricted seeding values for 32-bit. Yes, I could use unsigned long long and strtoull() etc instead, to get 64-bit numbers even on a 32-bit platform (though I'd have to convert that to a long to satisfy srand48() anyway. An alternative that I considered is to accept an argument -S xxxx:yyyy:zzzz with the three seed components set separately. I'd then have to modify the seed printing code as well as the parsing code. I use a separate program randseed to read numbers from /dev/urandom and format the result so it can be passed to programs which need a random seed:
$ randseed -b 8
0xF45820D2895B88CE
$

Is there a more efficient way of splitting a number into its digits?

I have to split a number into its digits in order to display it on an LCD. Right now I use the following method:
pos = 7;
do
{
LCD_Display(pos, val % 10);
val /= 10;
pos--;
} while (pos >= 0 && val);
The problem with this method is that division and modulo operations are extremely slow on an MSP430 microcontroller. Is there any alternative to this method, something that either does not involve division or that reduces the number of operations?
A note: I can't use any library functions, such as itoa. The libraries are big and the functions themselves are rather resource hungry (both in terms of number of cycles, and RAM usage).
You could do subtractions in a loop with predefined base 10 values.
My C is a bit rusty, but something like this:
int num[] = { 10000000,1000000,100000,10000,1000,100,10,1 };
for (pos = 0; pos < 8; pos++) {
int cnt = 0;
while (val >= num[pos]) {
cnt++;
val -= num[pos];
}
LCD_Display(pos, cnt);
}
Yes, there's another way, originally invented (at least AFAIK) by Terje Mathiesen. Instead of dividing by 10, you (sort of) multiply by the reciprocal. The trick, of course, is that in integers you can't represent the reciprocal directly. To make up for that, you work with scaled integers. If we had floating point, we could extract digits with something like:
input = 123
first digit = integer(10 * (fraction(input * .1))
second digit = integer(100 * (fraction(input * .01))
...and so on for as many digits as needed. To do this with integers, we basically just scale those by 232 (and round each up, since we'll use truncating math). In C, the algorithm looks like this:
#include <stdio.h>
// here are our scaled factors
static const unsigned long long factors[] = {
3435973837, // ceil((0.1 * 2**32)<<3)
2748779070, // ceil((0.01 * 2**32)<<6)
2199023256, // etc.
3518437209,
2814749768,
2251799814,
3602879702,
2882303762,
2305843010
};
static const char shifts[] = {
3, // the shift value used for each factor above
6,
9,
13,
16,
19,
23,
26,
29
};
int main() {
unsigned input = 13754;
for (int i=8; i!=-1; i--) {
unsigned long long inter = input * factors[i];
inter >>= shifts[i];
inter &= (unsigned)-1;
inter *= 10;
inter >>= 32;
printf("%u", inter);
}
return 0;
}
The operations in the loop will map directly to instructions on most 32-bit processors. Your typical multiply instruction will take 2 32-bit inputs, and produce a 64-bit result, which is exactly what we need here. It'll typically be quite a bit faster than a division instruction as well. In a typical case, some of the operations will (or at least with some care, can) disappear in assembly language. For example, where I've done the inter &= (unsigned)-1;, in assembly language you'll normally be able to just use the lower 32-bit register where the result was stored, and just ignore whatever holds the upper 32 bits. Likewise, the inter >>= 32; just means we use the value in the upper 32-bit register, and ignore the lower 32-bit register.
For example, in x86 assembly language, this comes out something like:
mov ebx, 9 ; maximum digits we can deal with.
mov esi, offset output_buffer
next_digit:
mov eax, input
mul factors[ebx*4]
mov cl, shifts[ebx]
shrd eax, edx, cl
mov edx, 10 ; overwrite edx => inter &= (unsigned)-1
mul edx
add dl, '0'
mov [esi], dl ; effectively shift right 32 bits by ignoring 32 LSBs in eax
inc esi
dec ebx
jnz next_digit
mov [esi], bl ; zero terminate the string
For the moment, I've cheated a tiny bit, and written the code assuming an extra item at the beginning of each table (factors and shifts). This isn't strictly necessary, but simplifies the code at the cost of wasting 8 bytes of data. It's pretty easy to do away with that too, but I haven't bothered for the moment.
In any case, doing away with the division makes this a fair amount faster on quite a few low- to mid-range processors that lack dedicated division hardware.
Another way is using double dabble. This is a way to convert binary to BCD with only additions and bit shifts so it's very appropriate for microcontrollers. After splitting to BCDs you can easily print out each number
I would use a temporary string, like:
char buffer[8];
itoa(yourValue, buffer, 10);
int pos;
for(pos=0; pos<8; ++pos)
LCD_Display(pos, buffer[pos]); /* maybe you'll need a cast here */
edit: since you can't use library's itoa, then I think your solution is already the best, providing you compile with max optimization turned on.
You may take a look at this: Most optimized way to calculate modulus in C
This is my attempt at a complete solution. Credit should go to Guffa for providing the general idea. This should work for 32bit integers, signed or otherwise and 0.
#include <stdlib.h>
#include <stdio.h>
#define MAX_WIDTH (10)
static unsigned int uiPosition[] = {
1u,
10u,
100u,
1000u,
10000u,
100000u,
1000000u,
10000000u,
100000000u,
1000000000u,
};
void uitostr(unsigned int uiSource, char* cTarget)
{
int i, c=0;
for( i=0; i!=MAX_WIDTH; ++i )
{
cTarget[i] = 0;
}
if( uiSource == 0 )
{
cTarget[0] = '0';
cTarget[1] = '\0';
return;
}
for( i=MAX_WIDTH -1; i>=0; --i )
{
while( uiSource >= uiPosition[i] )
{
cTarget[c] += 1;
uiSource -= uiPosition[i];
}
if( c != 0 || cTarget[c] != 0 )
{
cTarget[c] += 0x30;
c++;
}
}
cTarget[c] = '\0';
}
void itostr(int iSource, char* cTarget)
{
if( iSource < 0 )
{
cTarget[0] = '-';
uitostr((unsigned int)(iSource * -1), cTarget + 1);
}
else
{
uitostr((unsigned int)iSource, cTarget);
}
}
int main()
{
char szStr[MAX_WIDTH +1] = { 0 };
// signed integer
printf("Signed integer\n");
printf("int: %d\n", 100);
itostr(100, szStr);
printf("str: %s\n", szStr);
printf("int: %d\n", -1);
itostr(-1, szStr);
printf("str: %s\n", szStr);
printf("int: %d\n", 1000000000);
itostr(1000000000, szStr);
printf("str: %s\n", szStr);
printf("int: %d\n", 0);
itostr(0, szStr);
printf("str: %s\n", szStr);
return 0;
}

SSE shifting integers

I'm trying to understand how shifting with SSE works, but I don't understand the output gdb gives me. Using SSE4 I have a 128bit vector holding 8 16bit unsigned integers (using uint16_t). Then I use the intrinsic _mm_cmpgt_epi16 to compare them against some value, this function puts in all 0 or 1 bits into the bits used to store the ints. So far so good, using gdb I get:
(gdb) p/t sse_res[0]
$3 = {1111111111111111111111111111111111111111111111110000000000000000, 1111111111111111111111111111111111111111111111110000000000000000}
Then I would like to shift them to the right (is that correct?) so I just get a numerical value of 1 in case it's true. GDB then gives me an output which I don't understand:
(gdb) p/t shifted
$4 = {11101000000000010010000000000000110000000000000000011, 100111000000000001011000000000001001000000000000001111}
It's not even of the same length as the first, why is this? Just to try it out I used the following intrinsic to shift it one bit to the right:
shifted = _mm_srli_epi16(sse_array[i], 1);
I expected it to shift in just one zero at the right end of every 16bit block.
Update:
I wrote a small example to test the thing with the bitmask, it works fine, but I still don't understand gdbs behavior:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <tmmintrin.h>
#include <smmintrin.h>
void print128_num(__m128i vector)
{
uint16_t *values = (uint16_t*) &vector;
printf("Numerical: %i %i %i %i %i %i %i %i \n",
values[0], values[1], values[2], values[3], values[4], values[5],
values[6], values[7]);
}
int main (int argc, char **argv)
{
uint16_t nums[] = {1, 57, 33, 22, 88, 99, 9, 73};
__m128i *nums_sse = (__m128i*)(&nums);
print128_num(*nums_sse);
// vector of 42
__m128i mm42 = _mm_set1_epi16(42);
__m128i sse_res = _mm_cmpgt_epi16(*nums_sse, mm42);
printf("Result of the comparison\n");
print128_num(sse_res);
// bitmask
__m128i mask = _mm_set1_epi16(1);
__m128i finally = _mm_and_si128(sse_res, mask);
printf("Result of the masking\n");
print128_num(finally);
uint16_t* sse_ptr = (uint16_t*)(&finally);
uint32_t result = sse_ptr[0] + sse_ptr[1] + sse_ptr[2] + sse_ptr[3]
+ sse_ptr[4] + sse_ptr[5] + sse_ptr[6] + sse_ptr[7];
printf("Result: %i numbers greater 42\n", result);
return 0;
}
Breakpoint 1, main (argc=1, argv=0x7fff5fbff3b0) at example_comp.c:44
44 printf("Result: %i numbers greater 42\n", result);
(gdb) p/t sse_res
$1 = {11111111111111110000000000000000, 1111111111111111000000000000000011111111111111111111111111111111}
(gdb) p/t mask
$2 = {1000000000000000100000000000000010000000000000001, 1000000000000000100000000000000010000000000000001}
(gdb) p/t finally
$3 = {10000000000000000, 1000000000000000000000000000000010000000000000001}
(gdb) p result
$4 = 4
(gdb)
My gdb version: GNU gdb 6.3.50-20050815 (Apple version gdb-1472) (Wed Jul 21 10:53:12 UTC 2010)
Compiler flags: -Wall -g -O0 -mssse3 -msse4 -std=c99
I don't understand exactly what you're trying to do here, but maybe you can clarify it for us.
So, you have 8 signed integers packed in each of two variables, which you test for greater than. The result looks like it shows that the first 3 are greater, the next is not, the next 3 are greater, the last is not. (_mm_cmpgt_epi16 assumes signed integers in the reference I found.)
Then you want to tell if "it" is true, but I'm not sure what you mean by that. Do you mean they are all greater? (If so, then you could just compare the result against MAX_VALUE or -1 or something like that.)
But the last step is to shift some data to the right piecewise. Notice that is not the same variable as sse_res[0]. Were you expecting to shift that one instead?
Without knowing what was in the data before shifting, we can't tell if it worked correctly, but I assume that gdb is omitting the leading zeroes in its output, which would explain the shorter result.
0000000000011101 29 was 58 or 59
0000000000100100 36 was 72 or 73
0000000000011000 24 was 48 or 49
0000000000000011 3 was 6 or 7
0000000000100111 39 was 78 or 79
0000000000010110 22 was 44 or 45
0000000000100100 36 was 72 or 73
0000000000001111 15 was 30 or 31
Do these numbers look familiar?
Update:
Thanks for the updated code. It looks the integers are packed in the reverse order, and the leading zeroes left off in the gdb output.

Resources