How can i calculate in C power of 2, without pow function?
For example, after keyboard input 4, the result to be 16?
I know that, for example, 2^5 can be typing similar like 2^1*2^5 (I don't know if this idea can help)
To calculate 2N in C, use 1 << N.
If this may exceed the value representable in an int, use (Type) 1 << N, where Type is the integer type you want to use, such as unsigned long or uint64_t.
<< is the left-shift operator. It moves bits “left” in the bits that represent a number. Since numbers are represented in binary, moving bits left increases the powers of 2 they represent. Thus, 12 represents 1, 102 represents 2, 1002 represents 4, and so on, so 1 shifted left N positions represents 2N.
Numbers can be represented in binary form. For example, if integers are stored using 32 bits, 1 is stored like this:
00000000 00000000 00000000 00000001
And the value is the result of 1 x (20)
If you do a left-shift operation your value will be stored as this:
00000000 00000000 00000000 00000010
That means that now the result is result of 1 x (21)
Bit used to store a type is sizeof(type)x8, because a byte is 8 bit.
So best method is to use shift:
The left-shift of 1 by exp is equivalent to 2 raised to exp.
Shift operators must not be used for negative exponents in case of pow. The result is an undefined behaviour.
Another case of undefined behavior is the one of shifting the number equal to or more than N, in case of that number is stored in N bits.
#include <stdio.h>
#include <stdlib.h>
int main() {
int exp;
printf("Please, insert exponent:\n");
if (scanf("%d", &exp) != 1) {
printf("ERROR: scanf\n");
exit(EXIT_FAILURE);
}
if (exp < 0) {
printf("ERROR: exponent must be >= 0\n");
exit(EXIT_FAILURE);
}
printf("2^(%d) = %d\n", exp, 1 << exp);
exit(EXIT_SUCCESS);
}
You can also do it creating a ricorsive function (int) -> int:
int my_pow(int exp) {
If (exp < 0 ) {
return -1;
}
if (exp == 0) {
return 1;
}
if (exp > 0) {
return 2 * my_pow(exp-1);
}
}
Using it as main:
int main() {
int exp;
scanf("%d" &exp);
int res = my_pow(exp);
if (res == -1) {
printf("ERROR: Exponent must be equal or bigger than 0\n");
exit(EXIT_FAILURE);
}
printf("2^(%d) = %d", exp, res);
return 0;
}
Related
I want to apply a bitmask to a number that will mimic the absolute value function for 2's complement encoded signed 32 bit integers. So far, I have
int absoluteValue(int x) {
int sign = x >> 31; //get most significant byte...all 1's if x is < 0, all 0's if x >= 0
int negated = (~x + 1) & sign; //negates the number if negative, sets to 0 if positive
//what should go here???
}
Am I going in the right direction? I'm not really sure where to go from here (mostly just how to apply a mask to keep the original positive value). I also don't want to use any conditional statements
Bizarre question. What about
return (negated << 1) + x;
So put together this makes:
int absoluteValue(int x) {
int sign = x >> 31; //get most significant byte...all 1's if x is < 0, all 0's if x >= 0
int negated = (~x + 1) & sign; //negates the number if negative, sets to 0 if positive
return (negated << 1) + x;
}
The last part
negated = (~x + 1) & sign;
is wrong, you are going to get either 1 or 0, you have to create a mask with all
first 31 bits to 0 and only the last one to either 0 or 1.
Assuming that for you target you are dealing with 32 bit integers with 2
complement, you can do this:
#include <stdio.h>
// assuming 32bit, 2 complement
int sign_inverse(int n)
{
int mask = ~n & 0x80000000U;
if(n == 0)
mask = 0;
return (~n + 1) | mask;
}
int main(void)
{
int a = 5;
int b = -4;
int c = 54;
int d = 0;
printf("sign_inverse(%d) = %d\n", a, sign_inverse(a));
printf("sign_inverse(%d) = %d\n", b, sign_inverse(b));
printf("sign_inverse(%d) = %d\n", c, sign_inverse(c));
printf("sign_inverse(%d) = %d\n", d, sign_inverse(d));
return 0;
}
but you need at least 1 if for the case of 0, because the mask for 0 is 0x80000000.
The output of this is:
$ ./b
sign_inverse(5) = -5
sign_inverse(-4) = 4
sign_inverse(54) = -54
sign_inverse(0) = 0
Please note that two's complement representation is not guaranteed, and also the behaviour of operator >> on signed values, where the result get's "filled" with 1-bits is implementation defined (cf., for example, cppreference.com/arithmetic operations):
For negative LHS, the value of LHS >> RHS is implementation-defined
where in most implementations, this performs arithmetic right shift
(so that the result remains negative). Thus in most implementations,
right shifting a signed LHS fills the new higher-order bits with the
original sign bit (i.e. with 0 if it was non-negative and 1 if it was
negative).
But if you take this for given, and if you just want to use bit wise operations and operator +, you are already going into the right direction.
The only thing is that you should take into account the mask you create ( i.e. your sign) in that you toggle the bits of x only in the case where x is negative. You can achieve this by the XOR-operator as follows:
int x = -3000;
unsigned int mask = x >> 31;
int sign = mask & 0x01;
int positive = (x^mask) + sign;
printf("x:%d mask:%0X sign:%d positive:%d\n",x,mask,sign,positive);
For example, the binary conversion OF 233 is 11101001 and would like to transform it to something like 1110|1001
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, j, r, decimal, binary[20];
while(1)
{
printf("\n\nPLEASE ENTER ANY DECIMAL NUMBER: ");
scanf("%d", &decimal);
int n = decimal;
i = 0;
while (decimal > 0)
{
r = decimal % 2;
binary[i] = r;
decimal = decimal / 2;
i++;
}
printf("\n BINARY EQUIVALENT OF %d is; ", n);
for (j = i - 1; j >= 0; j--)
{
printf("%d", binary[j]);
}
}
return 0;
}
I bet this is a rookie question for some of you, but I could use your help, thanks
You can for example add a condition into the second look of 'j' and after you print 4 digits you add a |
for (int j=i-1; j>=0; j--) {
printf( "%d",binary[j]);
if(j%4==0 && j!=0)
printf("|");
}
Funnily enough I was just doing this yesterday. This probably not the best way to do this but it works.
char* hex_to_bin (unsigned char c) {
static char bin[10];
strcpy (bin, "");
char* mappings[] = {
"0000",
"0001",
"0010",
"0011",
"0100",
"0101",
"0110",
"0111",
"1000",
"1001",
"1010",
"1011",
"1100",
"1101",
"1110",
"1111"
};
sprintf (bin, "%s %s", mappings [(c/16) % 16], mappings[c % 16]);
return bin;
}
void print_bin (void * ptr, size_t size) {
int i;
for (i = size - 1; i >= 0 ; i--) {
unsigned char c = ((char*)ptr)[i];
printf ("%s ", hex_to_bin(c));
}
}
To use:
int k = 431;
print_bin (&k, sizeof (int)); // Of course you can put any pointer here
It should print this:
0000 0000 0000 0000 0000 0001 1010 1111
Notice that in the for I iterate from the size to 0. This is specific for Little Endian processors. If you have a Big Endian processor that you will have to go from 0 to size
If you want just to print it I suggest to make use of bitwise operands and bit shift.
Make a little research about bit shifting in C and bitwise operands (if you don't know yet of course) and then see the code and explanation below.
This is a more simplified code and more performatic too, and you will save memory with variable declarations.
Little explanation:
Bitwise operand compare each single bit of one or two variables.
Bitshift allow you to deslocate the bits of a variable to a direction the number of times you want.
See the code bellow:
#include <stdio.h>
void main() {
int i, decimal;
//The mask to compare just one bit
int mask=0b10000000;
printf("\n\nPLEASE ENTER ANY DECIMAL NUMBER: ");
scanf("%d", &decimal);
//Loopping 8 bits only
for(i=0;i<8;i++) {
/**
* Here you are doing the "magic", see how:
* You're using AND bitwise operand to compare just one bit at time starting for the MSB as you can see in first mask value
* So, first comparison with AND is you're value, for example 254, with mask shifted of 'i' bits, i value is 0 here
* The first comparison so is: (255)11111110 -> YOUR INT VALUE
* (AND)& 10000000 -> MASK
* Result: 10000000 -> THE RESULT OF: decimal&mask
* But this result in decimal is 128 and you want to show just 1 or 0, being 1 for everything that is not and 0 and 0 only for 0 results
* Here I suggest a technique, use the NOT logical operand to invert the value logically and the do it again, as bellow:
* !10000000 result in 0 and !0 result in 1 or 00000001, this way you can show if the bit is HIGH or DOWN.
* Keep doing it for the other bits, let see more 2:
* -----------------------------------------------------------------------------------------------
* Now i = 1 (second time in for loop), so mask is shifted 1 bit to right and mask is 01000000
* Making the same comparison (255)11111110 -> YOUR INT VALUE
* (AND)& 01000000 -> MASK
* Result: 01000000 -> THE RESULT OF: decimal&mask
* When you invert the result twice the result is 1 again.
* ------------------------------------------------------------------------------------------------
* Now i = 7 (last (seventh) time in for loop), so mask is shifted 7 bits to right and mask is 00000001
* Making the same comparison (255)11111110 -> YOUR INT VALUE
* (AND)& 00000001 -> MASK
* Result: 00000000 -> THE RESULT OF: decimal&mask
* When you invert the result twice the result is now 0. Because 0&1 is 0, when inverted it is 1 and inverting again it turns 0.
*
*/
printf("%d", !(!(decimal&mask>>i)));
if(i==3) printf(" "); //If it is on the fourth bit will print a space
}
}
You can use a mask and bitwise operators shift << and AND &. If you step through the code in your debugger you will see how it works.
void displayBits(unsigned);
int main(int args, char *argsv[]){
unsigned x;
printf("Enter an unsigned integer %u\n", x );
scanf("%u",&x);
displayBits(x);
return 0;
}
void displayBits(unsigned value){
const int SHIFT = 8*sizeof(unsigned)-1;
const unsigned MASK = 1 << SHIFT;
printf("%u = ", value);
unsigned c;
for(c=1; c<=SHIFT + 1; c++){
if(value & MASK){
printf("%d", 1);
}
else
{
printf("%d",0);
}
if(c%8==0)
printf("|");
value <<=1;
}
}
So have a signed decimal number that can be represented with 16 bits, in a char*. I want to have a char* of that number in 2s compliment binary. So I want to go from "-42" to "1111111111010110" (note all 16 bits are shown) in C. Is there a quick and dirty way to do this? Some library function perhaps? Or do I have to crank out a large-ish function myself to do this?
I'm aware that strtol() may be of some use.
There isn't a standard library function that can generate binary strings as you describe.
However it is not particularly difficult to do.
#include <stdio.h>
#include <stdint.h>
#include <ctype.h>
int main(int argc, char ** argv)
{
while(--argc >= 0 && ++argv && *argv){
char const * input = *argv;
if(! input)
continue;
uint32_t value = 0;
char negative = 0;
for(; *input; input++){
if (isdigit(*input))
value = value * 10 + (*input -'0');
else if (*input == '-' && value == 0)
negative = 1;
else {
printf("Error: unexpected character: %c at %d\n", *input, (int)(input - *argv));
continue; // this function doesn't handle floats, or hex
}
}
if (value > 0x7fff + negative){
printf("Error: value too large for 16bit integer: %d %x\n", value, value);
continue; // can't be represented in 16 bits
}
int16_t result = value;
if (negative)
result = -value;
for (int i=1; i <= 16; i++)
printf("%d", 0 != (result & 1 << (16-i)) );
printf("\n");
}
}
That function handles all valid 16 bit values and leverages the fact that the architecture stores integers as two's complement values. I'm not aware of an architecture that doesn't, so it's a fairly reasonable assumption.
Note that two's complement INT_MIN != -1 * INT_MAX.
This is handled by adding the negative flag to the validity check before conversion from unsigned 32bit to signed 16bit.
./foo 1 -1 2 -2 42 -42 32767 -32767 32768 -32768
0000000000000001
1111111111111111
0000000000000010
1111111111111110
0000000000101010
1111111111010110
0111111111111111
1000000000000001
Error: value too large for 16bit integer: 32768 8000
1000000000000000
fitsBits - return 1 if x can be represented as an
n-bit, two's complement integer.
1 <= n <= 32
Examples: fitsBits(5,3) = 0, fitsBits(-4,3) = 1
Legal ops: ! ~ & ^ | + << >>
My code is the following:
int fitsBits(int x, int n) {
int twos = ~x + 1; //two's complement
int ans;
ans = (twos >> (n);
ans = !ans;
return ans;
}
Working it on paper, it seems to work correctly but it fails when actually tested and I'm not sure why.
I'm assuming you are working on a 2s complement machine (vice sign-magnitude or some other kind of arithmetic) and need to avoid loops and conditionals as well. This is clearly some kind of puzzle, so let's not worry about portability and assume 32-bit ints.
If the value is positive, all bits from n-1 through the highest order bit of the int must be zeros. If the value is negative, the same bits must be ones. So one approach is to check those bits for the correct value.
This is equivalent to checking whether x >> (~0+n) is all zeros if x is positive and all ones otherwise. It "shifts out" the bits that are free to have any value.
We can also construct a mask that's all zeros if x is positive, else ones, with x >> 31.
Finally, we can check equality of any ints a and b using !(a ^ b).
Putting all this together, you'd get:
int fitBits(int val, int nbits) {
return !((val >> 31) ^ (val >> (~0 + nbits)));
}
You want the log base 2.
#include <stdio.h>
int fitsBits(unsigned int v, unsigned int n) {
unsigned int r = 0; // lg(v)
while (v >>= 1) {
r++;
}
if(r >= n) return 1;
return 0;
}
int main () {
printf(" 5,3 => %d\n", fitsBits( 5,3));
printf(" -4,3 => %d\n", fitsBits(-4,3));
}
output:
5,3 => 0
-4,3 => 1
I know how to convert a float into it's binary representation using % 2 and / 2, but is there a shortcut or cleaner way of doing this? Is what I am doing even considered representing a float bitwise? Because I am supposed to be using bitwise comparison between two float numbers, but I'm not sure if that means using bitwise operations.
For example to obtain the binary representation for a number I'd store the resultant of a number like 10 % 2 into an array until the number reached 0 within a while loop and if the array were to be printed backwards it would represent the number in binary.
array[] = num % 2;
num = num / 2;
What I did was use the method above for two float numbers, loaded them up with their own individual arrays, and compared them both through their arrays.
I have them set up in IEEE floating point format within their arrays as well.
EDIT: I have to compare two numbers of type float by using bitwise comparison and operations to see if one number is greater, less than, or if they are equal with the floats represented in biased exponent notation. The specifics are that it tests whether a floating point number number1 is less than, equal to or greater than another floating point number number2, by simply comparing their floating point representations bitwise by using bitwise comparisons from left to right, stopping as soon as the first differing bit is encountered.
No, it won't. Dividing a float by 2 will result in half of the number like this:
#include <stdio.h>
int main(void)
{
float x = 5.0f;
float y = x / 2;
printf("%f\n", y);
}
Result:
2.50000
see? It has nothing to do with bits.
Binary representation of floating numbers consists of mantissa, exponent and a sign bit, which means that unlike for normal integers, the tricks you've mentioned won't apply here. You can learn more about this by reading an article on Wikipedia on IEEE floating points.
To make sure two floats have exactly the same bit configurations, you could compare their content using memcmp which compares things byte-by-byte, with no additional casts/arithmetic/whatever:
#include <stdio.h>
int main(void)
{
float x = 5.0f;
float y = 4.99999999999999f; //gets rounded up to 5.0f
float z = 4.9f;
printf("%d\n", memcmp(&x, &y, sizeof(float)) == 0);
printf("%d\n", memcmp(&x, &z, sizeof(float)) == 0);
}
...will print 1 and 0 respectively. You can also inspect the individual bits this way (e.g. by operating on a *(char*)&x.
This compares two IEEE 32-bit floats bit by bit, returning -1, 0, or 1, and also indicating the bit at which they differ. They can be compared as sign-and-magnitude numbers. The function float_comp below first compares them bit-by-bit as uint32_t and negates the comparison if they differ in the sign bit (bit 31).
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
static int float_comp(float f1, float f2, int *bit)
{
const uint32_t *a, *b;
int comp = 0;
a = (const uint32_t *)(const void *)&f1;
b = (const uint32_t *)(const void *)&f2;
for (*bit = 31; *bit >= 0; (*bit)--) {
if ((*a & (UINT32_C(1) << *bit))
&& !(*b & (UINT32_C(1) << *bit))) {
comp = 1;
break;
}
if (!(*a & (UINT32_C(1) << *bit))
&& (*b & (UINT32_C(1) << *bit))) {
comp = -1;
break;
}
}
if (*bit == 31)
comp = -comp; /* sign and magnitude conversion */
return comp;
}
int main(int argc, char **argv)
{
float f1, f2;
int comp, bit;
if (argc != 3) {
fprintf(stderr, "usage: %s: float1 float2\n", argv[0]);
return 2;
}
f1 = strtof(argv[1], NULL);
f2 = strtof(argv[2], NULL);
comp = float_comp(f1, f2, &bit);
if (comp == 0)
printf("%.8g = %.8g\n", f1, f2);
else if (comp < 0)
printf("%.8g < %.8g (differ at bit %d)\n", f1, f2, bit);
else
printf("%.8g > %.8g (differ at bit %d)\n", f1, f2, bit);
return 0;
}
Doing what you said will not give you the bits of floating point representation. Instead use union to convert between float and integer representations and print bits as usual:
#include <stdio.h>
#include <stdint.h>
typedef union {
uint32_t i;
float f;
} float_conv_t;
void
int_to_bin_print(uint32_t number)
{
char binaryNumber[33];
int i;
for (i = 31; i >= 0; --i)
{
binaryNumber[i] = (number & 1) ? '1' : '0';
number >>= 1;
}
binaryNumber[32] = '\0';
fprintf(stdout, "Number %s\n", binaryNumber);
}
int main(void) {
float_conv_t f;
f.f = 10.34;
int_to_bin_print(f.i);
f.f = -10.34;
int_to_bin_print(f.i);
f.f = 0.1;
int_to_bin_print(f.i);
f.f = 0.2;
int_to_bin_print(f.i);
return 0;
}
Output:
Number 01000001001001010111000010100100
Number 11000001001001010111000010100100
Number 00111101110011001100110011001101
My goal is to compare two floating point numbers by comparing their
floating point representations bitwise.
Then you can compare raw memory using memcmp:
float f1 = 0.1;
float f2 = 0.2;
if (memcmp(&f1, &f2, sizeof(float)) == 0)
// equal
SYNOPSIS
#include
int memcmp(const void *s1, const void *s2, size_t n);
DESCRIPTION
The memcmp() function compares the first n bytes (each interpreted as unsigned char) of the memory areas s1 and s2.
RETURN VALUE
The memcmp() function returns an integer less than, equal to, or greater than zero if the first n bytes of s1 is found,
respectively, to
be less than, to match, or be greater than the first n bytes of s2.