Not understanding the calculation - c

I have following C program, and I'm not understanding the output of the following program.
#include <stdio.h>
int main()
{
int a,b, *p1, *p2, x,y,z;
a=12;
b=4;
p1=&a;
p2=&b;
x=*p1 * *p2-6;
y=4* - *p2 / *p1+10;
printf("y=%d", y);
return 0;
}
The output of the program is 9. But what is the meaning of 4*?

What is the meaning of 4*
The * there is the multiplication operator. Only one operand, 4, is shown in that extract. The full multiplication is:
4* - *p2
which is more clearly written as
4 * -(*p2)
Write out the expression, substituting the values. We can ignore x since it is not used. Which leaves us:
y= 4* - *p2 / *p1+10;
And *p2 is b which is 4. And *p1 is a which is 12. So the expression is:
y = 4 * -4 / 12 + 10;
And this evaluates as:
y = ((4 * -4) / 12) + 10;
Which is
y = (-16 / 12) + 10;
Which is
y = -1 + 10;

The spacing in this line might be causing confusion:
y=4* - *p2 / *p1+10;
This is equivalent to:
y = 4 * (-*p2) / *p1 + 10;
but the spacing makes it look like a subtraction.

The code
4* - *p2
means
4 * (-*p2)
So * means simple multiplication here.

Get familiar with the C precedence and associativity table:
The statements will be evaluated like this (parentheses added for clarity):
x = ((*p1) * (*p2)) - 6;
x = ((12) * (4)) - 6
x = (48) - 6
x = 42
y = (4 * (-(*p2)) / (*p1)) + 10;
y = (4 * (-4) / (12)) + 10
y = (-16 / 12) + 10
y = -1 + 10
y = 9

Related

Someone please explain me the logic behind this opration [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
#include<stdio.h>
int main(){
int a=10,b=3,c=2,d=4,result;
result = a+a*-b/c%d+c*d;
printf("%d",result);
}
How is this program giving 15 as the output.. I did not understand the logic behind the operation.. Can someone please tell me how calculation is done?
int a = 10, b = 3, c = 2, d = 4, result;
result=a+a*-b/c%d+c*d; // original line, with no spaces added
result = a + (a * (-b) / c % d) + (c * d);
result = 10 + (10 * -3 / 2 % 4) + (2 * 4);
result = 10 + (-30 / 2 % 4) + 8;
result = 10 + (-15 % 4) + 8;
result = 10 + (-3) + 8;
result = 15;
Note that the *, / and % operators have higher precedence than + and that those first three operators have equal precedence and left-to-right associativity. Note also that the unary minus operator (as in -b) has higher precedence than multiplication.
So, adding parentheses to highlight the operators' bindings and order-of-evaluation, and a couple of lines to keep track of the intermediate results, we see the following:
#include<stdio.h>
int main(){
int a=10, b=3, c=2, d=4, result;
result = a + ( ( ( (a*(-b)) ) / c ) % d ) + (c*d);
// ^-30 ^-15 ^-3 ^ 8
// ^ a + -3 = 7 ^ 7 + 8 = 15
printf("%d",result);
}
The relevant code:
int a=10,b=3,c=2,d=4,result;
result=a+a*-b/c%d+c*d;
Now processing this as a compiler would, following the rules of operator precedence:
// Unary minus
result = 10 + 10 * (-3) / 2 % 4 + 2 * 4;
// Multiplication, division, and remainder, with left-to-right associativity.
result = 10 + (-30) / 2 % 4 + 8;
result = 10 + (-15) % 4 + 8;
result = 10 + (-3) + 8;
// Addition and subtraction, with left-to-right associativity.
result = 15;
Note that according to the C99 specification, a == (a / b) * b + a % b must hold for the remainder operation with a negative number.

Solving compound assignment expressions

Okay, I know the output for the expression (x *= y = z = 4;) is 40; but how exactly did we get 40? Can you please show me step by step.
I thought the precedence is from right to left so (2 * 4) = (z =4), I don't understand
#include <stdio.h>
#define PRINTX printf("%d\n",x)
int main (void){
int x = 2, y, z;
x *= 3 + 2;
PRINTX;
x *= y = z = 4;
PRINTX;
x = y == z;
PRINTX;
x == ( y = z );
PRINTX;
return 0;
}
No, the only way that assignment can be evaluated here is right to left.
First, note that x *= 99, for example, is shorthand for x = x * 99.
With that said,
x *= y = z = 4;
is equivalent to
z = 4;
y = z;
x *= y; // This is shorthand for x = x * 4
Consider what would happen if you tried to evaluate it the other way around:
// y is unininitialized
x *= y;
y = z;
z = 4;
It would fail.
So really,
// x = 2
int x = 2, y, z;
// x = x * (3 + 2) = x * 5 = 2 * 5 = 10
x *= 3 + 2;
// x = x * 4 = 10 * 4 = 40
x *= y = z = 4;
This can be rewritten as
int x, y, z;
x = 2; // x = 2
x = x * (3 + 2); // This is 2 * 5, so x = 10 after this
z = 4; // z = 4
y = z; // y = 4
x = x * y; // x = 10 * 4 = 40
And that's how you end up with 40.
All of the assignment operators have equal precedence, and right-to-left associativity (which affects what happens when multiple operators of equal precedence are present in an expression).
This means x *= y = z = 4 is equivalent to x *= (y = (z = 4)). z = 4 must be evaluated first (which assigns z to 4, and gives a result of 4). The assignment y = ... then gives the value y the value of 4, and also produces a result of 4. The assignment x *= ... then multiples x (which has a value 10) by 4, giving a result of 40.
(The reason x *= 3 + 2 gives x the value 10 is that addition has higher precedence than assignment, so x *= 3+2 is equivalent to x *= (3 + 2) rather than (x *= 3) + 2.)
If the assignment operators were instead left-to-right associative, x *= y = z = 4 would be equivalent to (((x *= y) = y) = z) = 4 which would not compile.
You have:
int x = 2, y, z;
x *= 3 + 2;
This is a shorthand for x = x * (3 + 2), which evaluates to 10 given that x starts at 2.
PRINTX;
x *= y = z = 4;
After this, y == z and both are set to 4; and x is 4 times its previous value of 10, hence 40.
PRINTX;
x = y == z;
This compares y and z; they're equal, so x is assigned 1 (comparisons always evaluate to 0 or 1).
PRINTX;
x == ( y = z );
This assigns z to y (leaving the value unchanged at 4); nominally, this is compared with x but the compiler can ignore the comparison. Therefore, x is unchanged and still 1.

Finding sum of x^k from k= 0 to n in O(logn) time

So my question is how to do this in C more specifically. I'm aware that O(logn) usually means that we'll be using recursion by somehow splitting one of the parameters.
What I'm trying to achieve is the sum of k = 0 to n of xn.
for example exponent_sum(x, n) would be the parameters in this case.
Then,
exponent_sum(4, 4) would be 40 + 41 + 42 + 43 + 44 = 341.
I'm not sure where to start. Some hints would be really appreciated.
One way to look at the sum is as a number in base x consisting of all 1s.
For e.g, 44 + 43 + 42 + 41 + 40 is 11111 in base 4.
In any base, a string of 1s is going to be equal to 1 followed by a string of the same number of 0s, minus 1, divided by the base minus 1.
For e.g:
in base 10: (1000 - 1) / 9 = 999 / 9 = 111
in base 16: (0x10000 - 1) / 0xF = 0xFFFF / 0xF = 0x1111
in base 8: (0100 - 1) / 7 = 077 / 7 = 011
etc
So put these together and we can generalize that
exponent_sum(x, n) = (x (n + 1) - 1) / (x - 1)
For example, exponent_sum(4, 4) = (45 - 1) / 3 = 1023 / 3 = 341
So the big O complexity for it will be the same as for computing xn
Let me add another proof for the sake of completeness:
s = 1 + x1 + x2 + ... + xn
Then
xs = x(1 + x1 + x2 + ... + xn) = x1 + x2 + ... + xn + xn+1 = s - 1 + xn+1
Solving for s
(x - 1)s = xn+1 - 1,
s = (xn+1 - 1)/(x - 1)
Another way to see the solution is like this: suppose the sum is S written as
S = 1 + x + x^2 + ... + x^k
Then if we multiply both sides of it by x we get
S*x = x * (1 + x + x^2 + ... + x^k)
= x + x^2 + ... + x^k + x^(k+1)
then add 1 to both sides
S*x + 1 = 1 + x + x^2 + ... + x^k + x^(k+1)
= (1 + x + x^2 + ... + x^k) + x^(k+1)
= S + x^(k+1)
which means
S*x - S = x^(k+1) - 1
S*(x - 1) = x^(k+1) - 1
so
S = (x^(k+1) - 1) / (x - 1)
Use the theory Of geometric progression. where
sum = (first-term(pow(common-ratio,number-of-terms)-1))/(common-ratio-1);
here first-term is obviously 1;
Common-ratio= number itself;
number-of-terms=number+1;
But common-ratio should be greater than 1;
For
Common-ratio=1;
Sum=number*number-of-terms.
You can evaluate the sum directly, without using the geometric progression formula. This has the advantage that no division is required (which is necessary if, for example, you want to adapt the code to return the result modulo some large number).
Letting S(k) to be the sum x^0 + ... + x^{k-1}, it satisfies these recurrence relations:
S(1) = 1
S(2n) = S(n) * (1 + x^n)
S(2n+1) = S(n) * (1 + x^n) + x^{2n}
Using these, the only difficulty is arranging to keep a running value of xp to use as x^n. Otherwise the algorithm is very similar to a bottom-up implementation of exponentiation by squaring.
#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
int64_t exponent_sum(int64_t x, int64_t k) {
int64_t r = 0, xp = 1;
for (int i = 63; i >= 0; i--) {
r *= 1 + xp;
xp *= xp;
if (((k + 1) >> i) & 1) {
r += xp;
xp *= x;
}
}
return r;
}
int main(int argc, char *argv[]) {
for (int k = 0; k < 10; k++) {
printf("4^0 + 4^1 + ... + 4^%d = %" PRId64 "\n", k, exponent_sum(4, k));
}
return 0;
}

Numerical Evaluation of Pi

I would like to evaluate Pi approximately by running the following code which fits a regular polygon of n sides inside a circle with unit diameter and calculates its perimeter using the function in the code. However the output after the 34th term is 0 when long double variable type is used or it increases without bounds when double variable type is used. How can I remedy this situation? Any suggestion or help is appreciated and welcome.
Thanks
P.S: Operating system: Ubuntu 12.04 LTS 32-bit, Compiler: GCC 4.6.3
#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <stdlib.h>
#define increment 0.25
int main()
{
int i = 0, k = 0, n[6] = {3, 6, 12, 24, 48, 96};
double per[61] = {0}, per2[6] = {0};
// Since the above algorithm is recursive we need to specify the perimeter for n = 3;
per[3] = 0.5 * 3 * sqrtl(3);
for(i = 3; i <= 60; i++)
{
per[i + 1] = powl(2, i) * sqrtl(2 * (1.0 - sqrtl(1.0 - (per[i] / powl(2, i)) * (per[i] / powl(2, i)))));
printf("%d %f \n", i, per[i]);
}
return 0;
for(k = 0; k < 6; k++)
{
//p[k] = k
}
}
Some ideas:
Use y = (1.0 - x)*( 1.0 + x) instead of y = 1.0 - x*x. This helps with 1 stage of "subtraction of nearly equal values", but I am still stuck on the next 1.0 - sqrtl(y) as y approaches 1.0.
// per[i + 1] = powl(2, i) * sqrtl(2 * (1.0 - sqrtl(1.0 - (per[i] / powl(2, i)) * (per[i] / powl(2, i)))));
long double p = powl(2, i);
// per[i + 1] = p * sqrtl(2 * (1.0 - sqrtl(1.0 - (per[i] / p) * (per[i] / p))));
long double x = per[i] / p;
// per[i + 1] = p * sqrtl(2 * (1.0 - sqrtl(1.0 - x * x)));
// per[i + 1] = p * sqrtl(2 * (1.0 - sqrtl((1.0 - x)*(1.0 + x)) ));
long double y = (1.0 - x)*( 1.0 + x);
per[i + 1] = p * sqrtl(2 * (1.0 - sqrtl(y) ));
Change array size or for()
double per[61+1] = { 0 }; // Add 1 here
...
for (i = 3; i <= 60; i++) {
...
per[i + 1] =
Following is a similar method for pi
unsigned n = 6;
double sine = 0.5;
double cosine = sqrt(0.75);
double pi = n*sine;
static const double mpi = 3.1415926535897932384626433832795;
do {
sine = sqrt((1 - cosine)/2);
cosine = sqrt((1 + cosine)/2);
n *= 2;
pi = n*sine;
printf("%6u s:%.17e c:%.17e pi:%.17e %%:%.6e\n", n, sine, cosine, pi, (pi-mpi)/mpi);
} while (n <500000);
Subtracting 1.0 from a nearly-1.0 number is leading to "catastrophic cancellation", where the relative error in a FP calculation skyrockets due to the loss of significant digits. Try evaluating pow(2, i) - (pow(2, i) - 1.0) for each i between 0 and 60 and you'll see what I mean.
The only real solution to this issue is reorganizing your equations to avoid subtracting nearly-equal nonzero quantities. For more details, see Acton, Real Computing Made Real, or Higham, Accuracy and Stability of Numerical Algorithms.

How to get the 0's of digits when iterating through int's in C

I am trying to iterate through some number as 02100021, this is a routing number which needs to get validated if it is a proper routing number. Therefore I am using the ABA routing number validation check as 3*(d1+d4+d7) + 7*(d2+d5+d8) + (d3+d6+d9) where mod 10 = 0
Since I have the number in integer type, my first question is how can I iterate through such number with 0's in it, or if there is some easier way of iterating through mode and multiplying it with such number.
Thanks
If I understand correctly, 7 * (d2, d5, d8) should be 7 * (d2 + d5 + d8).
Zeros modulo 10 do not count.
bool correct(long x) {
long a = x / 10 + x / 10000 + x / 10000000L;
long b = x / 100 + x / 100000L + x / 100000000L;
long c = x / 1000 + x / 1000000L + x / 1000000000L;
int aba_checksum = (int)((3 * a + 7 * b + c) % 10);
return aba_checksum == 0;
}
Corrected for d[i] = digit * 10 ^ (9 - i)
bool correct(long x) {
long a = x / 100000000L + x / 100000L + x / 100;
long b = x / 10000000L + x / 10000L + x / 10;
long c = x / 1000000L + x / 1000L + x;
int aba_checksum = (int)((3 * a + 7 * b + c) % 10);
return aba_checksum == 0;
}
Modulo arithmetic can be done at the end.
To prevent overflow (to negative numbers) one might do it earlier, above even 7 * b does not overflow.

Resources