I can't print the results of bitwise operators [duplicate] - c

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Can I use a binary literal in C or C++?
I cannot display the results of bitwise operators in C. In the code below, a&b should be 100001 and a|b 111111. However, the printed results are different. I tried to do this with and without itoa, but to no avail. Why doesn't the program print the answers correctly?
#include<stdio.h>
#include<stdlib.h>
int main (int argc, char* argv[]) {
unsigned a = 101101;
unsigned b = 110011;
unsigned c = a&b;
unsigned d = a|b;
char s[100];
char t[100];
itoa(c,s,2);
itoa(d,t,2);
printf("%s\n",s); /* Shouldn't it produce 100001?
Instead I get 11000100010101001*/
printf("%s\n",t); /* Ought to print 111111.
Instead it prints 11010111111111111 */
return 0;
}
Thank You

The numbers you provide are decimal, while you meant to use binary. Try the following:
unsigned a = 0x2d; // 101101 b
unsigned b = 0x33; // 110011 b
Or for a GCC compiler use:
unsigned a = 0b101101;
unsigned b = 0b110011;

You need to express your numbers as decimal (e.g. 101101 becomes 45, 110011 becomes 51), ocatal (101101 becomes 055, 110011 is 063) or hexadecimal (as Eli shows, 0x2d and 0x33 respectively).
Some compilers MAY support binary, but most don't. Working directly in binary is painful anyways once numbers get more than about 8-12 bits long, so learning how to work with binary in either hex (most common these days) or octal (used to be popular in the 1970's, particularly on DEC equipment that used a lot of 3-bit combinations, so it made sense).
You could of course use strtol(str, NULL, 2) to translate a binary string to a long value.

The integers you have defined (a and b) are not defined using bits. You have defined integers that are 101101 and 110011. So even with proper display, that would not work.
What I recommend you to get more or less what you want is:
First properly define your number. Some C compilers (as far as I know, this is not standard) define the bit notation, so a would be: 0b101101 and b would b: 0b110011. That way:
unsigned a = 0b101101;
unsigned b = 0b110011;
Otherwise, you have to either define them using hexadecimal notation (0x....) or directly in 10-base. In first case, a would be: 0x2d or 45.
Furthermore, for the display, you have no way to display bits. So, you should to display with hexadecimal notation (which is more appropriate for that kind of things), using: printf("c: %#x", c);
It will output: c: 0x21.

Related

C output of hexadecimal division different from all other sources

I want to divide two hex numbers:
for example: 88555680/10000
Now, from online hex calculators, I find:
8855 as result here
8855.568 as result here
And in python I find:
>>> hex(int("0x88555680",16)//int("0x10000", 16))
'0x8855'
Here is my C code:
# include <stdio.h>
int main() {
int a = 0x88555680;
int b = 0x10000;
int c = a/b;
printf("a%x, b%x, c%x\n", a, b, c);
}
With output:
a88555680, b10000, cffff8856
In C, I find 8856, while with Python, and online calculators, I find 8855
Question: Why is the C output not 8855? Why is it 8856? Should it not be 8855.something and then truncated towards 0, thus 8855?
I'm very new to C, it might be an obvious error.
On common systems int is a 32-bit type whose max value is 0x7FFFFFFF. Your value of 0x88555680 is out of range for int. The compiler should warn you about this; if you don't see a warning then I recommend adjusting compiler settings.
Also your code causes undefined behaviour by using %x to print an int. The %x specifier may only be used for unsigned int.
To fix your code in this case use unsigned int instead of int for all 3 variables. If you want to deal with larger numbers you can use unsigned long long, or uint64_t. (In those cases you will need to update the printf format specifiers too).

I don't know how to convert 16 byte hexadecimal to floating point

Probably from the time I am trying to convert and wandering internet solely for the answer of this question but I could not find. I just got I can convert hexadecimal to decimal either by some serious programming or manually through math.
I am looking to convert. If there is any way to do that then please share. Well I have searched and found IEEE754 which seems not to be working or I am not comprehending it. Can I do it manually through any equation, I think I heard about it? Or a neat C program which may do it.
Please help! Any help would be highly appreciated.
You need to study the IEEE floating point spec.
This would be quite straightforward in Java. You have handy methods like Float.floatToRawIntBits(float x) and Float.intBitsToFloat(int x)
You might be able to do it with a union.
In C its a bit more hacky. You can abuse a union. Unions in C reuse the same memory for two different variables. A union like
union DoubleLong {
long l;
double d;
} u;
would allow you to treat the same bit of memory as either a long u.i or a double u.f. There are both 8 byte so they take the same space. So doing u.d = M_PI; printf("%lx\n", u.l); prints the binary representation of pi 0x400921fb54442d18.
For 16 byte we need the union to have an array or two 8 byte longs.
#include <stdio.h>
union Data {
long i[2];
long double f;
} u;
int main(int argc, char const *argv[]) {
// Using random IP6 address 2602:306:cecd:7130:5421:a679:6d71:a660
// Store in two separate 8-byte longs
u.i[0] = 0x2602306cecd7130;
u.i[1] = 0x5421a6796d71a660;
// Print out in hexidecimal
printf("%.15La %lx %lx\n", u.f,u.i[0],u.i[1]);
// print out in decimal
printf("%.15Le %ld %ld\n", u.f,u.i[0],u.i[1]);
return 0;
}
One problem is 16 byte hexadecimal floating point numbers might not be defined on you system. float is typically 32 bit - 4 byte, double is 64 bit - 8 byte. There is an long double type but on my mac its only 80-bit - 10 byte. It might be simpler to convert to two double precision numbers. So on my system only the last 4 hexadecimal digits of the second number are significant.
Not all hexadecimal numbers correspond to valid floating point numbers, a lot of values will correspond to NaN's. If the higher bits are 7FFF or FFFF (or 7FF, FFF for double) that will either give infinity of NaN.

Convert Int to Hexdecimal without using 'printf' (C Programming)

Is it possible to Convert Int to Hexdecimal without using 'printf'?
Best if the all the value are placed in the variable itself and some sample code with explanation.
The decimal and hexadecimal systems are just ways of expressing the value of the int. In a way "it is already a hexadecimal".
I think you can use itoa in stdlib.h :
char * itoa ( int value, char * str, int base ); or sprintf(str,"%x",value);
The documentation : itoa documentation
Of course it is possible. Just think about how printf itself was originally implemented...
I won't give you a full solution, only hints, based on which you can experiment with the implementation in code:
An 8-bit number can be expressed as 2 hex digits, which contain the higher and lower 4 bits, respectively. To get these bits, you can use the bit-shift (>>) and mask (&) operators.
Once you have a 4-bit value, you can easily map it to the correct hex digit using a sequence of ifs, or (as a more elegant solution) by indexing into a character array.
Hexdecival vs Decimal vs Binary..etc.. are only different bases that represent the same number. printf doesn't convert your number, it generates an hexdecimal string representation of your number. If you want to implement your own study how to make a conversion between decimal and hexdecimal bases.
Yes, it is definitely possible to convert an integer to a hexadecimal string without using the "printf" family of formatting functions.
You can write such a function by converting the number from base-10 (as we think about it) to base-16 (hexadecimal) and printing the digits in that representation (0-9A-F). This will require you to think a lot about the bases we use to represent numbers.
If you are referring to displaying an int as a hexadecimal number in C, than you will have to write a function that does the same thing as printf.
If you are referring to casting or internal representation, it can't be done because hexadecimal is not a data type.
An int is stored in your computer as a binary number. In fact, since hex can be interpreted as a shorthand for writing binary, you might even say that when you print out a decimal number using printf, it has to be converted from hex to decimal.
it's an example for convert a char array to hex string format
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
unsigned char d=255;
char hex_array[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char *array_to_hex_string(uint8_t data[],int size);
char test_data[3] = {'0',188,255};
int main()
{
printf("%s",array_to_hex_string(test_data,3));
return 0;
}
char *array_to_hex_string(uint8_t data[],int size){
int i,j;
char *hex_string = (char *)malloc((2*size) * sizeof(data[0]));
for(i=0;i<size;i++){
hex_string[j] = hex_array[(data[i]>>4)];
hex_string[j+1] = hex_array[(data[i] & 15)];
j +=2;
}
return (char *)hex_string;
}
cout << hex << intvar << endl;
But if you want an answer that gives you an A for your homework, you're not going to get lucky :)

Checking overflow in C

Let us have
int a, b, c; // may be char or float, anything actually
c = a + b;
let int type be represented by 4 bytes. Let's say a+b requires 1 bit more than 4 bytes (ie, let's say the result is 1 00....0 (32 zeroes, in binary)). This would result in C=0, and I am sure the computer's microprocessor would set some kind of overflow flag. Is there any built in method to check this in C?
I am actually working on building a number type that is 1024 bits long (for example, int is a built in number type that is 32 bits long). I have attempted this using unsigned char type arrays with 128 elements. I also need to define addition and subtraction operations on these numbers. I have written the code for addition but I am having problem on subtraction. I don't need to worry about getting negative results because the way I will call the subtracting function always ensures that the result of subtraction is always positive, but to implement the subtraction function I need to somehow get the 2's complement of the subtrahend, which is it self my custom 1024 bit number.
I am sorry if it is difficult to understand my description. If needed I will elaborate it more. I am including my code for the adding function and the incomplete subtracting function. the NUM_OF_WORDS is a constant declared as
#define NUM_OF_WORDS 128
Please let me know if you did not understand my question or any part of my code.
PS: I don't see how to upload attachments in this forum so I am directing you to another website. My code may be found there
click on download in this page
Incidentally, I found this
I intend to replace INT_MAX by UCHAR_MAX as my 1024 bit numbers consist of array of char types (8-bit variable)
Is this check sufficient for all cases?
Update:
Yes I am working on Cryptography.
I need to implement a Montgomery Multiplication routine for 1024 bit size integers.
I had also considered using GMP library but couldn't find out how to use it.
I looked up a tutorial and after a few small modifications I was able to build the GMP project file in VC++ 6 which resulted in a lot of .obj files, but now I am not sure what to do with them.
Still it would be good if I can write my own data types, as it will give me complete control over how the arithmetic operations on my custom data type work, and I also need to be able to extend it from 1024 bits to larger numbers in the future.
If you're adding unsigned numbers then you can do this
c = a+b;
if (c<a) {
// you'll get here if and only if overflow has occurred
}
and you may even find that your compiler is clever enough to implement it by checking the overflow or carry flag instead of doing an extra comparison. For instance, I just fed this to gcc -O3 -S:
unsigned int foo() {
unsigned int x=g(), y=h();
unsigned int z = x+y;
return z<0 ? 0 : z;
}
and got this for the key bit of the code:
movl $0, %edx
addl %ebx, %eax
cmovb %edx, %eax
where you'll notice there's no extra comparison instruction.
Contrary to popular belief, an int overflow results in undefined behavior. This means that once a + b overflows, it doesn't make sense to use this value (or do anything else, for that matter). The wrap-around is just what most machines happen to do in case of overflow, but they might as well explode.
To check whether an int overflow will occur when adding two non-negative integers a and b, you can do the following:
if (INT_MAX - b < a) {
/* int overflow when evaluating a+b */
}
This is due to the fact that if a + b > INT_MAX, then INT_MAX - b < a, but INT_MAX - b can not overflow.
You will have to pay special attention to the case where b is negative, which is left as an exercise for the reader ;)
Regarding your actual goal: 1024-bit numbers suffer from exactly the same overall issues as 32-bit numbers. It might be more promising to choose a completely different approach, e.g. representing numbers as, say, linked lists of digits, using a very large base B. Usually, B is chosen such that B = sqrt(INT_MAX), so multiplication of digits doesn't overflow the machine's int type.
This way, you can represent arbitrarily large numbers, where "arbitrary" means "only limited by the amount of main memory available".
If you are working with unisigned numbers, then if a <= UINT_MAX, b <= UINT_MAX, and a + b >= UINT_MAX, then c = (a + b) % UINT_MAX will always be smaller than a and b. And this is the only case where this can happen.
So you can detect overflow this way.
int add_return_overflow(unsigned int a, unsigned int b, unsigned int* c) {
*c = a + b;
return *c < a && *c < b;
}
Information which maybe useful in this subject :
Secure Coding in C and C++
IntSafe library
You can base a solution on a particular feature of the C language. According to the specification, when you add two unsigned ints, "the result value is congruent to the modulo 2^n of the true result" ("C - A reference manual" by Harbison and Steele). This means you can use some simple arithmetic checks to detect overflow:
#include <stdio.h>
int main() {
unsigned int a, b, c;
char *overflow;
a = (unsigned int)-1;
for (b = 0; b < 3; b++) {
c = a + b;
overflow = (a < b) ? "yes" : "no";
printf("%u + %u = %u, %s overflow\n", a, b, c, overflow);
}
return 0;
}
Just xor MSB of both operands and result. Result of this operation is overflow flag.
But that will not show you if result is correct or not. (it might be correct result even whit overflow) for instance 3 + (-1) is 2 whit overflow.
In order to figure that using signed arithmetic you need to check if both operdas were same sign (xor of MSB).
Once you add 1 to INT_MAX, you end up getting INT_MIN (i.e. overflow).
In C, there's no reliable way to test for overflow, because all 32 bytes are used to represent the integer (and not a state flag). You can only test to see if the number you get will be within a valid range, as in your link.
You'll get answers suggesting that you can test if (c < a), however note that you could overflow the value of a and/or b to the point where their addition forms a number greater than a (but still overflown)

C convert hex to decimal format

Compiling on linux using gcc.
I would like to convert this to hex. 10 which would be a.
I have managed to do this will the code below.
unsigned int index = 10;
char index_buff[5] = {0};
sprintf(index_buff, "0x%x", index);
data_t.un32Index = port_buff;
However, the problem is that I need to assign it to a structure
and the element I need to assign to is an unsigned int type.
This works however:
data_t.un32index = 0xa;
However, my sample code doesn't work as it thinks I am trying to convert
from an string to a unsigned int.
I have tried this, but this also failed
data_t.un32index = (unsigned int) *index_buff;
Many thanks for any advice,
Huh? The decimal/hex doesn't matter if you have the value in a variable. Just do
data_t.un32index = index;
Decimal and hex are just notation when printing numbers so humans can read them.
For a C (or C++, or Java, or any of a number of languages where these types are "primitives" with semantics closely matching those of machine registers) integer variable, the value it holds can never be said to "be in hex".
The value is held in binary (in all typical modern electronic computers, which are digital and binary in nature) in the memory or register backing the variable, and you can then generate various string representations, which is when you need to pick a base to use.
I agree with the previous answers, but I thought I'd share code that actually converts a hex string to an unsigned integer just to show how it's done:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *hex_value_string = "deadbeef";
unsigned int out;
sscanf(hex_value_string, "%x", &out);
printf("%o %o\n", out, 0xdeadbeef);
printf("%x %x\n", out, 0xdeadbeef);
return 0;
}
Gives this when executed:
emil#lanfear /home/emil/dev $ ./hex
33653337357 33653337357
deadbeef deadbeef
However, my sample code doesn't work as it thinks I am trying to convert from an string to a unsigned int.
This is because when you write the following:
data_t.un32index = index_buff;
you do have a type mismatch. You are trying to assign a character array index_buff to an unsigned int i.e. data_t.un32index.
You should be able to assign the index as suggested directly to data_t.un32index.

Resources