Hexadecimal comparison for big number in c program - c

#include<stdio.h>
long long int A = 0xAABBCCDDBBCCFFEE;
long long int B = 0xAACCCCDDBBDDFF00;
int array[8] = {'\0'};
int byte_compare(int A, int B)
{
int i = 0;
long long int j = 0xFF;
long long int C = A;
long long int D = B;
while(i < 8)
{
C = (j & A);
D = (j & B);
printf("C = %x\n",C);
printf("D = %x\n",D);
printf("j = %x\n",j);
if(C == D)
{
array[i] = 1;
}
else
{
array[i] = 0;
}
i++;
j = j << 8;
}
}
main()
{
int i = 0;
byte_compare(A,B);
while(i < 8)
{
printf("array[%d] - %d\n",i, array[i]);
i++;
}
}
long long int A = 0xAABBCCDDBBCCFFEE;
long long int B = 0xAACCCCDDBBDDFF00;
result = 10111010
when A and B byte number matches with each other it should print 1 otherwise 0.
for my above program it is printing output
C = ee
D = 0
j = ff
C = ff00
D = ff00
j = ff00
C = cc0000
D = dd0000
j = ff0000
C = bb000000
D = bb000000
j = ff000000
C = 0
D = 0
j = 0
C = 0
D = 0
j = 0
C = 0
D = 0
j = 0
C = 0
D = 0
j = 0
array[0] - 0
array[1] - 1
array[2] - 0
array[3] - 1
array[4] - 1
array[5] - 1
array[6] - 1
array[7] - 1
Not able to compare after first four byte please help me what datatype I should use instead above.

You have many problems in your code
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
void byte_compare(uint64_t C, uint64_t D, int *array)
{
int i = 0;
while (i < 8)
{
printf("C = %"PRIx64"\n" , (C&0xFF));
printf("D = %"PRIx64"\n\n", (D&0xFF));
if ((C&0xFF) == (D&0xFF))
{
array[i] = 1;
}
else
{
array[i] = 0;
}
i++;
C >>= 8;
D >>= 8;
}
}
int main(void)
{
int i = 0;
uint64_t A = UINT64_C(0xAABBCCDDBBCCFFEE);
uint64_t B = UINT64_C(0xAACCCCDDBBDDFF00);
int array[8] = {0};
byte_compare(A, B, array);
while (i < 8)
{
printf("array[%d] - %d\n", i, array[i]);
i++;
}
}
Correct type for your variables must be unsigned long long due to the literals: bit 63 is set to 1 so assign it to a signed variable causes overflow which invoke UB. Using stdint.h standard header you can use uint64_t that is clearer.
byte_compare function definition is wrong, you must pass parameters with correct type: unsigned long long (uint64_t). Moreover the function does not return an int so should be void.
printf with %x format specifier wants an unsigned int, not a uint64_t. Best thing to do is to use defined in inttypes.h standard header where all format specifier are well reported: in your case PRIx64 is the right one.
In your version of code you are left shifting a long long int that is used as mask to "select" the byte to check. It is plain wrong because last shift causes an overflow on a signed value that is UB as for point 1.
stdint.h has also macros that append the correct suffix to literals.
Another example using a mask:
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
void byte_compare(uint64_t C, uint64_t D, int *array)
{
uint64_t mask = UINT64_C(0xFF00000000000000);
while (mask > 0)
{
printf("C = %"PRIx64"\n" , (C&mask));
printf("D = %"PRIx64"\n\n", (D&mask));
if ((C&mask) == (D&mask))
{
*array = 1;
}
else
{
*array = 0;
}
mask >>= 8;
array--;
}
}
int main(void)
{
int i = 0;
uint64_t A = UINT64_C(0xAABBCCDDBBCCFFEE);
uint64_t B = UINT64_C(0xAACCCCDDBBDDFF00);
int array[8] = {0};
byte_compare(A, B, &array[7]);
while (i < 8)
{
printf("array[%d] - %d\n", i, array[i]);
i++;
}
}

Related

How do I use typeof with dynamic types?

I'm slightly confused about typeof and how to use it properly. I know typedefs exist but I imagine typedefs are more for static/compile time types where as typeof is dynamic?
In this code
int main()
{
int t[] = {0,1,2,3,4,5};
typeof(t) a;
for(int i = 0; i < 6; ++i){
a[i] = i;
}
return 0;
}
Since t is an array allocated on the stack is then typeof(t) a also an array allocated on the stack?
Or what if I made a pointer point to t, then made a type of p ?
int main()
{
int t[] = {0,1,2,3,4,5};
int* p = t;
typeof(p) a;
return 0;
}
Is a now just an integer pointer that hasn't been allocated?
Or if I allocate t dynamically then make a typeof t
int main()
{
int* t = malloc(6*sizeof(int));
for(int i = 0; i < 6; ++i){
t[i] = i;
}
typeof(t) a;
for(int i = 0; i < 6; ++i){
a[i] = i;//crashes
}
return 0;
}
Is this again just an integer pointer and allocation does not play a role?
Or what if I wanted to take a pointer but make a 2d array out of that pointer?
int main()
{
int* t = malloc(6*sizeof(int));
for(int i = 0; i < 6; ++i){
t[i] = i;
}
typeof(t) a[2][3];
printf("%d\n",a[0][1]);
return 0;
}
Is that valid?
int main()
{
int x = 2;
int y = 3;
typeof(int[x][y]) a;
for(int i = 0; i < 2; ++i){
for(int j = 0; j < 3; ++j){
a[i][j] = i+j;
}
}
return 0;
}
Or is that valid? Is a already allocated on the stack here ? If it is, then is it using VLA to do a stack based allocation for the array?
Am I just over thinking what typeof does?
typeof is a gcc extension used mainly for macros.
All types in C are known to the compiler at compile time, avoid using typeof() in source code as it makes the code less readable and the type should be easy to find. typeof is not a C equivalent of the auto keyword used in C++ to let the compiler infer the type from the context. auto is a reserved keyword in C to specify automatic storage, which is implicit for local objects, hence the keyword is never used.
Here is an example of a macro that uses the typeof extension:
#include <stdio.h>
#define SWAP(x, y) do { typeof(x) *x__ = &(x), *y__ = &(y), t__ = *x__; \
*x__ = *y__; *y__ = t__; } while (0)
int main() {
int i1 = 1, i2 = 2;
unsigned u1 = 1, u2 = 2;
long l1 = 1, l2 = 2;
double d1 = 1, d2 = 2;
const char *str1 = "1", *str2 = "2";
struct { int x; } s1 = { 1 }, s2 = { 2 };
int a1[] = { 1, 2, 3 }, a2[] = { 4, 5, 6 };
SWAP(i1, i2);
SWAP(u1, u2);
SWAP(l1, l2);
SWAP(d1, d2);
SWAP(str1, str2);
SWAP(s1, s2);
for (int i = 0, j = 0; i < 3;) {
SWAP(a1[i++], a2[j++]);
}
printf("i1 = %d, i2 = %d\n", i1, i2);
printf("u1 = %u, u2 = %u\n", u1, u2);
printf("l1 = %ld, l2 = %ld\n", l1, l2);
printf("d1 = %g, d2 = %g\n", d1, d2);
printf("str1 = %s, str2 = %s\n", str1, str2);
printf("s1 = { %d }, s2 = { %d }\n", s1.x, s2.x);
printf("a1 = { %d, %d, %d }, a2 = { %d, %d, %d }\n",
a1[0], a1[1], a1[2], a2[0], a2[1], a2[2]);
return 0;
}
Output:
i1 = 2, i2 = 1
u1 = 2, u2 = 1
l1 = 2, l2 = 1
d1 = 2, d2 = 1
str1 = 2, str2 = 1
s1 = { 2 }, s2 = { 1 }
a1 = { 4, 5, 6 }, a2 = { 1, 2, 3 }
Note however that the SWAP macro can be defined in Standard C with the same semantics as:
#include <string.h>
#define SWAP(x, y) do { void *x__ = &(x), *y__ = &(y); \
size_t s__ = sizeof(x); \
unsigned char t__[s__]; \
memcpy(t__, x__, s__); \
memcpy(x__, y__, s__); \
memcpy(y__, t__, s__); \
} while (0)
There is no such thing as a "dynamic type" in C. Types are fully resolved in the compiler and then cease to exist. typeof is substituted as though it were a typedef for the declared type of its argument, which doesn't have to be a simple variable.
In your fourth example:
int main()
{
int* t = malloc(6*sizeof(int));
for(int i = 0; i < 6; ++i){
t[i] = i;
}
typeof(t) a[2][3];
printf("%d\n",a[0][1]);
return 0;
}
typeof(t) is precisely int* because that's what you declared t to be. So the new variable a has type int* [2][3] -- that is, an array of arrays of pointers to int. That's probably not what you want, since you try to print one of its (uninitialised) elements as though it were an integer. That suggest that the declaration you were looking for was:
typeof(*t) a[2][3];
In any event, how a variable is allocated and what its type is are two orthogonal concepts (although certain restrictions apply, notably that you cannot declare a VLA at global scope).
As another take-away, always enable compiler warnings. I suspect that reading the error messages would have helped with at least some of those examples.

Subtracting a sequence of numbers using for loop in C Programming

int myfunc(int a, int b)
{
int result = a;
for(int index = a - 1; index >= b; index--)
{
result -= index;
}
return result;
}
How to make this function subtract numbers from the smallest number to the greatest number depending on the values of a and b that I choose ? (e.g. if a = 5 and b = 8 , then the program would type 5-6-7-8 = -16)
You're going the "wrong direction". Look at what you want to do:
5-6-7-8 = -16
^ ^ ^ ^
a | | |
a+1| |
a+2|
a+3
So start at a+1 and count up to b
int result = a;
for(int index = a + 1; index <= b; index++)
{
result -= index;
}
// result = -16 for a=5, b=8
Demo
For starters the variable index is redundant.
To avoid an overflow (at least in most cases) the variable result should have the type long long int instead of int. For example if you will run your function like
myfunc( INT_MIN , INT_MIN + 3 );
(provided that you have included the header <limits.h>) when if the type of the variable result is int then the function will return the value -6 (actually the behavior is undefined in this case) while if the variable result has the type long long int then you will get the correct result 4294967290.
The function can look the following way
long long int myfunc( int a, int b )
{
if ( b < a )
{
int tmp = b;
b = a;
a = tmp;
}
long long int result = a;
while ( a < b )
{
result -= ++a;
}
return result;
}
Here is a demonstrative program.
#include <stdio.h>
long long int myfunc( int a, int b )
{
if ( b < a )
{
int tmp = b;
b = a;
a = tmp;
}
long long int result = a;
while ( a < b )
{
result -= ++a;
}
return result;
}
int main(void)
{
printf( "%lld\n", myfunc( 8, 5 ) );
return 0;
}
The program output is
-16

My CHAR to BINARY conversion into a ARRAY does not work

i had write a program, that convert a char to binary code... All were working when i had that code
int n, c, k;
n = character;
for (c = 7; c >= 0; c--)
{
k = n >> c;
if (k & 1)
printf("1");
else
printf("0");
}
But I must to write these values to an ARRAY and I edited code like u can see below and thats not worked.. Can you help me please?
void encode_char(const char character, bool bits[8]) {
int n, c, k;
n = character;
for (c = 7; c >= 0; c--)
{
k = n >> c;
if (k & 1)
bits[c] = "1";
else
bits[c] = "0";
}
printf("\n");
}
In a Arena (that controls the program) you can see error: Assertion 'encode_char('r', bits) => {0, 1, 1, 1, 0, 0, 1, 0}' failed. [got {1, 1, 1, 1, 1, 1, 1, 1}]]
Here's a possible implementation for the code:
#include <stdio.h>
#include <stdbool.h>
void encode_char(char character, bool bits[8]) {
for (int bit_index = 7; bit_index >= 0; bit_index--, character >>= 1)
bits[bit_index] = character & 1;
}
int main() {
bool bits[8];
encode_char('U', bits);
for (int bit_index = 0; bit_index < 8; bit_index++)
printf("%d", bits[bit_index]);
printf("\n");
return 0;
}
Some points:
You don't need so many variables for the bits extraction logic, you're already creating a new variable in the function, so just change its value.
Like the comments stated, you're comparing a bit and not a byte.

How to switch 2nd and 4th digit(before comma) in a double? C programming

So lets say the input is 45392.56, the output has to be 49352.56.
How can i program this in C?
#include <stdio.h>
#include <stdlib.h>
int dotPos(char arr[]) {
int i = 0;
while (arr[++i] != '.');
return i;
}
int main() {
double d = 45392.56;
int MAX = 100;
char arr[MAX];
sprintf(arr, "%f", d);
if (dotPos(arr) > 3) {
char aux = arr[1];
arr[1] = arr[3];
arr[3] = aux;
}
d = atof(arr);
printf("%.2f\n", d);
}
Output:
49352.56
Convert the number to a character array. Look at the sprintf function.
Swap the positions of the characters.
Convert the character array to double. Look at the atof function.
Avoiding conversion to string and back, take the integral part of the number, find the two values in position 1 and 3 (in decimal notation), and compute the value to add or substract to/from the original double.
this is (a-b) *pow(10,hipos) - (a-b) * pow(10,lopos)
#include <stdio.h>
long finddiff(unsigned long val, unsigned lpos, unsigned rpos);
int main(void) {
double d = 45392.56;
unsigned long u;
long dif;
u = d;
dif = finddiff(u,3,1);
d += dif;
printf("%.2f\n", d);
return 0;
}
long finddiff(unsigned long val, unsigned lpos, unsigned rpos)
{
long res;
unsigned pos, ll, rr;
if (lpos < rpos) return finddiff(val, rpos,lpos);
for (pos=0; pos < rpos; pos++) { val /= 10; }
rr = val %10;
for (; pos < lpos; pos++) { val /= 10; }
ll = val %10;
// fprintf(stderr, "%u,%u\n", ll,rr);
res = rr-ll;
for (; pos > rpos; pos--) { res *= 10; }
res -= rr-ll;
for (; pos > 0; pos--) { res *= 10; }
// fprintf(stderr, "%u,%u,%ld\n", ll,rr, res);
if (ll > rr) res = -res;
else if (rr > ll) {;}
else res = 0;
return res;
}
BTW: this will fail miserably for values whose integer part is larger than the maximum log int, eg 6.3E23 .
For negative numbers some additional logic should be added.

C: Best way to index the digits in an integer

If I have an
int i = 11110001
How would I be able to convert this int into an int array where
int array[8] = {1, 1, 1, 1, 0, 0, 0, 1}
Using a little different approach and snprintf:
#include <stdio.h>
int main (void) {
int i = 11110001;
char arr[9]; //8 digits + \0
int array[8];
if ((snprintf(arr,9,"%d", i) == 8) { //return the 8 characters that were printed
int c;
for(c = 0; c < 8; c++)
array[c] = arr[c] - '0';
}
return 0;
}
P.S: I'm assuming positive values only
You may try like this:
#include <math.h>
char * convertNumber(unsigned int i) {
/* unsigned int length = (int)(log10((float)i)) + 1; */
/* char * arr = (char *) malloc(length * sizeof(char)), * x = arr; */
char * arr = malloc(8);
char * x = arr;
do
{
*x++ = i% 10;
i/= 10;
} while (i != 0);
return arr;
}
Try this :
#include<stdio.h>
void convert_int_to_array(unsigned int);
int main()
{
unsigned int a = 12345678;
convert_int_to_array(a);
return 0;
}
void convert_int_to_array(unsigned int a)
{
int array[25]; // array large enough for an integer
int i = 0, count = 0;
unsigned int num = a;
memset(array, '\0', 20); // I've not included the header file for this.
// gives a warning on compilation.
while(num > 0)
{
array[i] = num % 10;
num = num / 10;
++i;
++count;
}
for(i = count; i>=0;--i)
{
printf("array[%d] = %d\n",i, array[i]);
// or
printf("%d", array[i]);
// dont use both the printf statements, else you will see a
// messed up output.
}
}
BINARY REPRESENTATION :
#include<stdio.h>
struct bit
{
int a : 1;
};
int main()
{
struct bit b;
int d ,f,i;
d=f=256; // take any number of your choice
printf("binary representation of 256:\n");
for(i = 15; i>=0 ; i--) //assuming that the number wont have more than
// 15 DIGITS
{
f=f>>i;
b.a = f;
//d= d>>1;
f=d;
printf("%d",b.a);
}
return 0;
}

Resources