Exponent not working properly in C - c

When i run the following code
/*Program to find the greatest common divisor of two nonnegative integer
values*/
#include <stdio.h>
int main(void){
printf(" n | n^2\n");
printf("-----------------\n");
for(int n = 1; n<11; n++){
int nSquared = n^2;
printf("%i %i\n",n,nSquared);
}
}
The table that gets returned to the terminal displays as follows
n | n^2
-----------------
1 3
2 0
3 1
4 6
5 7
6 4
7 5
8 10
9 11
10 8
why does the "n^2" side generate the wrong numbers? And is there a way to write superscripts and subscripts in C, so I do not have to display "n^2" and can display that side of the column as "n²" instead?

Use pow function from math.h.
^ is the bitwise exclusive OR operator and has to nothing to do with a power function.

The ^ is the XOR operation. You'd either want to use the math.h function "pow", or write your own.

^ is the bitwise xor operator. You should use the pow function declared in the math.h header.
#include <stdio.h>
#include <math.h>
int main(void) {
printf(" n | n^2\n");
printf("-----------------\n");
for(int n = 1; n < 11; n++){
int nSquared = pow(n, 2); // calculate n raised to 2
printf("%i %i\n", n, nSquared);
}
return 0;
}
Include the math library by the flag -lm for gcc compilation.

As others have pointed out, the problem is that ^ is the bitwise xor operator. C has no exponentiation operator.
You're being advised to use the pow() function to compute the square of an int value.
That's likely to work (if you're careful), but it's not the best approach. The pow function takes two double arguments and returns a double result. (There are powf and powl functions that operator on float and long double, respectively.) That means that pow has to be able to handle arbitrary floating-point exponents; for example, pow(2.0, 1.0/3.0) will give you an approximation of the cube root of two.
Like many floating-point operations, pow is subject to the possibility of rounding errors. It's possible that pow(3.0, 2.0) will yield a result that's just slightly less than 9.0; converting that to int will give you 8 rather than 9. And even if you manage to avoid that problem, converting from integer to floating-point, performing an expensive operation, and then converting back to integer is massive overkill. (The implementation might optimize calls to pow with integer exponents, but I wouldn't count on that.)
It's been said (with slight exaggeration) that premature optimization is the root of all evil, and the time spent doing the extra computations is not likely to be noticeable. But in this case there's a way to do what you want that's both simpler and more efficient. Rather than
int nSquared = n^2;
which is incorrect, or
int nSquared = pow(n, 2);
which is inefficient and possibly unreliable, just write:
int nSquared = n * n;

Related

Why is pow() function in C giving wrong answer when it is odd exponential of 10 in a loop? [duplicate]

This question already has answers here:
Why pow(10,5) = 9,999 in C++
(8 answers)
Closed 2 years ago.
#include <stdio.h>
#include <math.h>
int main()
{
int loop, place_value=0, c = 5;
for(loop = 0; loop < c; loop++)
{
place_value = 0;
place_value = pow(10, loop);
printf("%d \n", place_value);
}
return 0;
}
This code gives
10
99
1000
9999
Why is 99 and 9999 there in 3rd and 5th line instead of 100 and 10000 respectively?
When asking for power normally, it gives right answer.
#include <stdio.h>
#include <math.h>
int main()
{
printf ("%d", (int) pow (10,3 ));
return 0;
}
1000
pow is a difficult routine to implement, and not all implementations give good results. Roughly speaking, the core algorithm for pow(x, y) computes a logarithm from (a part of) x, multiplies it by y, and computes an exponential function on the product. Doing this in floating-point introduces rounding errors that are hard to control.
The result is that the computed result for pow(10, 4) may be something near 10,000 but slightly less or greater. If it is less, than converting it to an integer yields 9999.
When you use arguments hard-coded in source code, the compiler may compute the answer during compilation, possibly using a different algorithm. For example, when y is three, it may simply multiply the first argument by itself, as in x*x*x, rather than using the logarithm-exponent algorithm.
As for why the low result happens with the odd numbers you have tested, consider what happens when we multiply 5.45454545 by various powers of 10 and round to an integer. 5.45454545 rounds down to 5. 54.5454545 rounds up to 55. 545.454545 rounds down to 545. The rounding up or down is a consequence of what fraction happens to land beyond the decimal point. For your cases with pow(10, loop), the bits of the logarithm of 10 may just happen to give this pattern with the few odd numbers you tried.
pow(x, y) function translate more or less to exp(log(x) * y), which will give a result that is not quite the same as x ^ y.
In order to solve this issue you can round this:
round(pow(x, y))
The rule of thumb: never use floating point functions (especially such a complicated ones like pow or log) with integer numbers.
Simply implement integer pow
unsigned intpow(unsigned x)
{
unsigned result = 1;
while(x --) result *= 10;
return result;
}
it will be much faster or even (the fastest one)
int intpow1(unsigned x)
{
const static unsigned vals[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, /* ... */};
#if defined(CHECK_OVERFLOW)
if(x >= sizeof(vals)/ sizeof(vals[0])) return -1;
#endif
return vals[x];
}

pow() function giving wrong answer [duplicate]

This question already has an answer here:
pow() function in C problems [duplicate]
(1 answer)
Closed 3 years ago.
I'm trying to multiply 2, 3 digit numbers.
I used 2 for loops (nested) and multiplied each digit of num1 with num2,
and shifted each result to the appropriate place using pow().
So the problem is pow(10,3) is coming out to be 299 instead of 300.
I haven't tried much as but used printf to find what is actually happening in the runtime and this is what I have found.
the values of tempR after shift should be
5,40,300,100,800,6000,1500,12000,90000
but are coming as
5,40,299,100,799,6000,1500,12000,89999
int main(void)
{
int result; // final result
int tempR; // temporary for each iteration
char a[] = "345"; // number 1
char b[] = "321"; // number 2
for(int i = 2;i>= 0 ; i --)
{
for(int j = 2;j >= 0 ; j --)
{
int shift = abs(i-2 + j -2);
printf("%d\n",shift); //used to see the values of shift.
//and it is coming as expected
tempR = (int)(b[i] - '0') * (int)(a[j] - '0');
printf("%d \n",tempR); // value to tempR is perfect
tempR = tempR*pow(10,shift);
printf("%d \n",tempR); // here the problem starts
result += tempR;
}
}
printf("%d",result);
}
Although IEEE754 (ubiquitous on desktop systems) is required to return the best possible floating point value for certain operators such as addition, multiplication, division, and subtraction, and certain functions such as sqrt, this does not apply to pow.
pow(x, y) can and often is implemented as exp(y * ln (x)). Hopefully you can see that this can cause result to "go off" spectacularly when pow is used with seemingly trivial integral arguments and the result truncated to int.
There are C implementations out there that have more accurate implementations of pow than the one you have, particularly for integral arguments. If such accuracy is required, then you could move your toolset to such an implementation. Borrowing an implementation of pow from a respected mathematics library is also an option, else roll your own. Using round is also a technique, if a little kludgy if you get my meaning.
Never use float functions for the integer calculations. Your pow result almost never will be precise. In this case it is slightly below 300 and the cast to integer makes it 299.
The pow function operates on doubles. Doubles use finite precision. Conversion back to integer chops rather than rounding.
Finite precision is like representing 1/3 as 0.333333. If you do 9 * 1/3 and chop to an integer, you'll get 2 instead of 3 because 9 * 1/3 will give 2.999997 which chops to two.
This same kind of rounding and chopping is causing you to be off by one. You could also round by adding 0.5 before chopping to an integer, but I wouldn't suggest it.
Don't pass integers through doubles and back if you expect exact answers.
Others have mentioned that pow does not yield exact results, and if you convert the result to an integer there's a high risk of loss of precision. Especially since if you assign a float type to an integer type, the result get truncated rather than rounded. Read more here: Is floating math broken?
The most convenient solution is to write your own integer variant of pow. It can look like this:
int int_pow(int num, int e)
{
int ret = 1;
while(e-- > 0)
ret *= num;
return ret;
}
Note that it will not work if e is negative or if both num and e is 0. It also have no protection for overflow. It just shows the idea.
In your particular case, you could write a very specialized variant based on 10:
unsigned int pow10(unsigned int e)
{
unsigned int ret = 1;
while(e-- > 0)
ret *= 10;
return ret;
}

How to sum large numbers?

I am trying to calculate 1 + 1 * 2 + 1 * 2 * 3 + 1 * 2 * 3 * 4 + ... + 1 * 2 * ... * n where n is the user input.
It works for values of n up to 12. I want to calculate the sum for n = 13, n = 14 and n = 15. How do I do that in C89? As I know, I can use unsigned long long int only in C99 or C11.
Input 13, result 2455009817, expected 6749977113
Input 14, result 3733955097, expected 93928268313
Input 15, result 1443297817, expected 1401602636313
My code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
unsigned long int n;
unsigned long int P = 1;
int i;
unsigned long int sum = 0;
scanf("%lu", &n);
for(i = 1; i <= n; i++)
{
P *= i;
sum += P;
}
printf("%lu", sum);
return 0;
}
In practice, you want some arbitrary precision arithmetic (a.k.a. bigint or bignum) library. My recommendation is GMPlib but there are other ones.
Don't try to code your own bignum library. Efficient & clever algorithms exist, but they are unintuitive and difficult to grasp (you can find entire books devoted to that question). In addition, existing libraries like GMPlib are taking advantage of specific machine instructions (e.g. ADC -add with carry) that a standard C compiler won't emit (from pure C code).
If this is a homework and you are not allowed to use external code, consider for example representing a number in base or radix 1000000000 (one billion) and code yourself the operations in a very naive way, similar to what you have learned as a kid. But be aware that more efficient algorithms exist (and that real bignum libraries are using them).
A number could be represented in base 1000000000 by having an array of unsigned, each being a "digit" of base 1000000000. So you need to manage arrays (probably heap allocated, using malloc) and their length.
You could use a double, especially if your platform uses IEEE754.
Such a double gives you 53 bits of precision, which means integers are exact up to the 53rd power of 2. That's good enough for this case.
If your platform doesn't use IEEE754 then consult the documentation on the floating point scheme adopted. It might be adequate.
A simple approach when you're just over the limit of MaxInt, is to do the computations modulo 10^n for a suitable n and you do the same computation as floating point computation but where you divide everything by 10^r.The former result will give you the first n digits while the latter result will give you the last digits of the answer with the first r digits removed. Then the last few digits here will be inaccurate due to roundoff errors, so you should choose r a bit smaller than n. In this case taking n = 9 and r = 5 will work well.

Does pow() work for int data type in C? [duplicate]

This question already has answers here:
Strange behaviour of the pow function
(5 answers)
Closed 7 years ago.
I was simply writing a program to calculate the power of an integer. But the output was not as expected. It worked for all the integer numbers except for the power of 5.
My code is:
#include <stdio.h>
#include <math.h>
int main(void)
{
int a,b;
printf("Enter the number.");
scanf("\n%d",&a);
b=pow(a,2);
printf("\n%d",b);
}
The output is something like this:
"Enter the number. 2
4
"Enter the number. 5
24
"Enter the number. 4
16
"Enter the number. 10
99
Can't we use pow() function for int data type??
Floating point precision is doing its job here. The actual working of pow is using log
pow(a, 2) ==> exp(log(a) * 2)
Look at math.h library which says:
###<math.h>
/* Excess precision when using a 64-bit mantissa for FPU math ops can
cause unexpected results with some of the MSVCRT math functions. For
example, unless the function return value is stored (truncating to
53-bit mantissa), calls to pow with both x and y as integral values
sometimes produce a non-integral result. ... */
Just add 0.5 to the return value of pow and then convert it to int.
b = (int)(pow(a,2) + 0.5);
So, the answer to your question
Does pow() work for int data type in C?
Not always. For integer exponentiation you could implement your own function (this will work for 0 and +ve exp only):
unsigned uint_pow(unsigned base, unsigned exp)
{
unsigned result = 1;
while (exp)
{
if (exp % 2)
result *= base;
exp /= 2;
base *= base;
}
return result;
}
there is no int based pow. What you are suffering from is floating point truncation.
an int based pow is too constrained (the range of inputs would quickly overflow an int). In many cases int based pow, like in your case where its powers of 2 can be done efficiently other ways.
printf("%a", pow(10, 2)) and see what you get; I expect you'll see you don't quite get 100. Call lround if you want to round instead of truncating.
The C library function double pow(double x, double y)
It takes double type

Mathematical task with point numbers

I just started to study about C Programing.
I want to write a program to solve this mathematical task (1/2*r2*3.14)
This is the code that I wrote:
#include <stdio.h>
#include <conio.h>
main()
{
int r=5;
float sum;
sum = 1/2*r^2*3.14;
printf("%f", sum);
getch();
}
but there is an error and I don`t know what the mistake is.
First I thought that there is something wrong about the number 3.14, but when I changed it to 3 the program ran but the answer was 6.0000 but it should be 37.5
In C there is no operator for power calculation. ^ is used as XOR operator. You need to use library function pow for power calculations.
sum = 1.0 / 2 * pow(r,2) * 3.14;
Note that I changed 1/2 to 1.0/2 because 1/2 will always give 0 and the result you will get is 0.
^ is bitwise XOR operator. You have to use pow() for your purpose
sum = 1.0/2.0*pow(r,2)*3.14;
Your code will give you 6.000. Because ^ is using as xor operator
1/2*r^2*3 = (0)d ^ (6)d = (000)b ^ (110)b = (110)b = (6)d
But, 3.14 instead of 3 will give you error
1/2*r^2*3.14
Because, Xor operator don't take double as operand
The ^ operator is not for power raising you can write it explicitly
#include <stdio.h>
#include <conio.h>
main()
{
int r=5;
float sum;
/* 1/2 * r^2 * pi <- this is the expression */
sum = 1.57 * r * r;
printf("%f", sum);
getch();
}
the expression has no meaning in the program except for someone reading it, so you can add a comment and write the values directly.
And in case you are going to raise to a higher power just use the pow() function.
Also, if you skip the .0 the compiler assumes the values as integers, and 1/2 is 0.5 truncated it yeilds 0, 1./2 would also work, but not 1/2.

Resources