Why this type of power function work? - c

res = 1;
for ( i = 1; i <= n; i <<= 1 ) // n = exponent
{
if ( n & i )
res *= a; // a = base
a *= a;
}
This should be more effective code for power and I don't know why this works.
First line of for() is fine I know why is there i <<= i. But I don't understand the line where is: if ( n & i ). I know how that works but I don't know why...

Let us say you have a binary representation of an unsigned number. How do you find the decimal representation?
Let us take a simple four bit example:
N = | 0 | 1 | 0 | 1 |
-----------------------------------------
| 2^3 = 8 | 2^2 = 4 | 2^1 = 2 | 2^0 = 1 |
-----------------------------------------
| 0 | 4 | 0 | 1 | N = 4 + 1 = 5
Now what would happen if the base wasn't fixed at 2 for each bit but instead was the square of the previous bit and you multiply the contribution from each bit instead of adding:
N = | 0 | 1 | 0 | 1 |
----------------------------
| a^8 | a^4 | a^2 | a^1 |
----------------------------
| 0 | a^4 | 0 | a^1 | N = a^4 * a^1 = a^(4+1) = a^5
As you can see, the code calculate a^N

Related

value over written in the array during loop

I am currently trying to convert an equation into simpler form and found out that my codes are over writing the value at the end of the loop.
I have found out similar discussions but not exactly what I am looking for. Most of articles were using other languages so I couldn't get the answer.
Any answers are appreciated and thanks in advance.
followings are my code
int index = 0;
int result = 0;
char tresult[100];
char *equation[100] = { NULL, };
char *temp = strtok(input, " ");
for(int i = 1; i < x; i = i + 2)
{
char *temp_sign = equation[i];
if(*temp_sign == '*')
{
result = atoi(equation[i - 1]) * atoi(equation[i +1]);
sprintf(tresult, "%d", result);
equation[i - 1] = tresult;
sprintf(equation[i], "%d", 0);
sprintf(equation[i + 1], "%d", 0);
}
}
for(int j = 0; j < x; j++)
{
printf("%s ", equation[j]);
}
Expected input
5 * 3 + 1 * 2
targeted output
15 0 0 + 2 0 0
I will remove 0 by adding extra codes to make it as
15 + 2
but currently, my output looks like
2 0 0 + 2 0 0
When I print out the value in the loop, all the values were correctly shown. What may be the cause of such problem?
It might be easier to understand if we draw out the pointer instead.
Assuming that input is initially equal to "5 * 3 + 1 * 2", then after the loop equation will look something like this:
+-------------+
| equation[0] | ------------------------\
+-------------+ |
| equation[1] | --> | input[2] | ... | | +------------+-----+
+-------------+ >--> | tresult[0] | ... |
| equation[2] | --> | input[4] | ... | | +------------+-----+
+-------------+ |
| equation[3] | ------------------------/
+-------------+
| equation[4] | --> | input[10] | ... |
+-------------+
| equation[5] | --> | input[12] | ... |
+-------------+
As seen in the above "drawing" both equation[0] and equation[3] will be pointing to the first character of the single array tresult.
And tresult will always contain the contents last written into it with sprintf(tresult, "%d", result). Which in your example will be "2".

How come the following program output is 5, not 4? Could anyone explain?

I came upon a program which outputs 5. I don't know how. Please explain.
int main(void) {
int t[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, *p = t;
p += 2;
p += p[-1];
printf("\n%d",*p);
return 0;
}
I expect the output to be 4.
the pointer moves from t[0] to t[2] here(p+=2;). In the next statement p+= p[-1], I believe pointer moves to t[1] whose value is 2 first and so increased by 2. So I expected output to be 4.
but the actual output is 5. Anyone, please explain?
p = t; // p = &t[0]
p += 2; // p = &t[2]
p += p[-1]; // p += 2; // p = &t[4]
At first, the pointer p points to the beginning of the array t. So it should be something like
p--
|
v
------------------------------------------
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
------------------------------------------
Now by
p += 2
p is increment according to pointer arithmetic. So that p is now pointing to 3.
p----------
|
v
------------------------------------------
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
------------------------------------------
p[-1] is same as *(p-1). ie, the value at the address p-1. This value is 2.
------ p[-1] or *(p-1)
|
|
------|-----------------------------------
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
------------------------------------------
After adding 2 to the current value of p, p would now be pointing to 5.
p------------------
|
v
------------------------------------------
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
------------------------------------------
So, when you print the value of *p, 5 is output.

Binary addition

I am trying to understand how Bitwise operators work in C, but I have an misunderstanding about the << operator.
I have the following code:
#include <stdio.h>
int Add(int x, int y);
int Add(int x, int y)
{
while ( y != 0 ) /// Iterate till there is no carry
{
int carry = x & y; /// carry now contains common set bits of x and y
x = x ^ y; /// Sum of bits of x and y where at least one of the bits is not set
y = carry << 1; /// Carry is shifted by one so that adding it to x gives the required sum
}
return x;
}
int main( void )
{
printf( "%d", Add( 13, 17 ) );
return 0;
}
If I understand correctly works like this:
First Iteration:
|=======================================|
| |
| while ( y != 0 ) |
| while ( 17 != 0 ) |
| while ( 10001 != 00000 ) |
| |
| c = x & y; |
| 1 = 13 & 17 |
| 00001 = 01101 & 10001 |
| |
| x = x ^ y |
| 28 = 13 ^ 17 |
| 11100 = 01101 ^ 10001 |
| |
| y = c << 1 |
| 17 = 1 << 1 |
| 10001 = 00001 << 00001 |
| 00010 = 00001 << 00001 |
| |
|=======================================|
Second Iteration:
|=======================================|
| |
| while ( y != 0 ) |
| while ( 2 != 0 ) |
| while ( 00010 != 00000 ) |
| |
| c = x & y; |
| 0 = 28 & 2 |
| 00000 = 11100 & 00010 |
| |
| x = x ^ y |
| 30 = 28 ^ 2 |
| 11110 = 11100 ^ 00010 |
| |
| y = c << 1 |
| 2 = 0 << 1 |
| 00010 = 00000 << 00001 |
| 00000 = 00000 << 00001 |
| |
|=======================================|
Then Y becomes 0 and X returns 30.
Now in the following code I have an issue:
#include <stdio.h>
int main( void )
{
int x = 13;
int y = x << 1; /// 11010 = 01101 << 00001
x = 0 << 1; /// 00000 = 00000 << 00001
printf("y = %d\n", y ); /// 26 | 11010
printf("x = %d\n", x ); /// 26 | 11010
return 0;
}
Here if I understand right we shift all bits one to the left:
int y = x << 1; /// 11010 = 01101 << 00001
But what exactly happens here:
x = 0 << 1; /// 00000 = 00000 << 00001
Does x get cleared and filled with the rezult of 0 << 1 ?
Does x get cleared and filled with the rezult of 0 << 1 ?
x is just assigned the value of the expression 0 << 1. Zero left or right shifted by any amount remains 0.
So this means that the representation of the First and Second Iteration is correct?
It is correct, except that substitution of the old values of variables (on the lhs) is a bit confusing as in the following cases.
17 = 1 << 1
10001 = 00001 << 00001
and
2 = 0 << 1
00010 = 00000 << 00001
Instead depict it as:
y = 1 << 1
y = 00001 << 00001
and
y = 0 << 1
y = 00000 << 00001
n << k is actually n * (2^k) as long as you have enough bits available to keep all of the resulting bits. So 0 << k is 0 * (2^k) = 0 whatever the (positive integer) value of k is.
Note that for usual 32 bit integers, a number on p = 17 bits or more, like 65537 (0x0001_0001), will stop behaving like the multiplication once k is greater or equal to (32+1)-p = (32+1)-17 = 16, as for example 65537 << 16 is 0x1_0001_0000 which is using 33 bits and is truncated to 0x0001_0000 = 65536.
With 65536 << 15 you may also start having strange results as the result, 0x1000_0000, is changing the left most bit, which is the sign bit if you're not using unsigned values...

use ((c1^c2) & ~32) to test if c1 and c2 are the same character in different case

I saw some code like this
if( ((c1^c2) & ~32)==0 )
{
...
}
In this snippet the code likely mean that if the if statement is true, then c1 and c2 are the same character in different case, meaning that one of those is +32 or -32 away from the other. Why is that?
I did test myself and discover that in some case it is true while in others not:
printf("%d", (65^97)& ~32); //output is 0. right
printf("%d", (97^65)& ~32); //output is 0. right
printf("%d", (50^82)& ~32); //output is 64!! not the same though 82-50=32
Why is that? what is the magic in it?
(c1^c2) & ~32) xors c1 and c2, the result contains the bits that are in both characters and & with ~32 clears (ignores) the bit 5. (It is zeroed whether it was same in both or not). Comparing this with zero, checks if all the bits other than bit 5 are same.
This can be used to check if 2 letters are equal ignoring their case in ascii representation if you are sure that atleast c1 or c2 is a valid latin character(a-z, A-Z).
To understand this, let's pick 2 characters with different case and compare them:
+---+---+---+---+---+---+---+---+
a | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 |
+---+---+---+---+---+---+---+---+
| x | | | | | |
+---+---+---+---+---+---+---+---+
A | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
a ^ A | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
32 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
~32 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 |
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
& | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+---+---+---+---+---+---+---+---+
You can try the same with j v/s J or t v/s z.
So there is no magic involved, only this logic.
Sometimes this condition is also written as:
if (ch1 == ch2 || (ch1 ^ 32) == ch2)
{
...
}

If I have a truth table, is there a way of determining the bitwise expression I need for that truth table?

I am attempting to do the following in c:
unsigned int mask;
unsigned int previous;
unsigned int new;
unsigned int out;
for( int i = 0; i < 8; ++i )
{
bool bit_set = GET_BIT( mask, i );
// If the mask bit is true, use the new bit, otherwise use the previous bit
SET_BIT( out, i, GET_BIT( bit_set ? new : previous, i ) );
}
However I think there may be an easier and quicker way using bitwise operations. I have the truth table but I don't know how to get the expression I need.
Truth table is:
m | p | n | o
0 | 0 | 0 | 0
1 | 0 | 0 | 0
0 | 1 | 0 | 1
1 | 1 | 0 | 0
0 | 0 | 1 | 0
1 | 0 | 1 | 1
0 | 1 | 1 | 1
1 | 1 | 1 | 1
How would I go about working this out?
Use Karnaugh Map - there is a solver available online. Pick "three values", enter the expected results for all eight combinations, and use the expression the solver produces:
F(m, p, n) = (p & !n) | (m & n)
EDIT : You can expand this solution to do the whole byte at once, rather than doing it one bit at a time, by using the ~ bitwise NOT operator:
result = (mask & new) | (~mask & previous);
If the mask bit is true, use the new bit, otherwise use the previous
bit
The natural way to express this (to me) is (mask & new) | (~mask & previous). That is to say, mask corresponding bits from new and previous, and add them together using OR.

Resources