Power function returns 1 less result - c

Whenever I input a number in this program the program return a value which is 1 less than the actual result ... What is the problem here??
#include<stdio.h>
#include<math.h>
int main(void)
{
int a,b,c,n;
scanf("%d",&n);
c=pow((5),(n));
printf("%d",c);
}

pow() returns a double, the implicit conversion from double to int is "rounding towards zero".
So it depends on the behavior of the pow() function.
If it's perfect then no problem, the conversion is exact.
If not:
1) the result is slightly larger, then the conversion will round it down to the expected value.
2) if the result is slightly smaller, then the conversion will round down which is what you see.
solution:
Change the conversion to "round to nearest integer" by using rounding functions
c=lround(pow((5),(n)));
In this case, as long as pow() has an error of less than +-0.5 you will get the expected result.

pow() takes double arguments and returns a double.
If you store the return value into an int and print that, you may not get the desired result.

If you need accurate results for big numbers, you should use a arbitrary precision math library like GMP. It's easy:
#include <stdio.h>
#include <math.h>
#include <gmp.h>
int main(void) {
int n;
mpz_t c;
scanf("%d",&n);
mpz_ui_pow_ui(c, 5, n);
gmp_printf("%Zd\n", c);
return 0;
}

You can use the %f format specifier while commanding printf func.You should see your result accurately. In %d format specifier the value tends to the final answer eg. 5^2=24.9999999999 and hence the answer shown is 24.

Related

Decimal To Binary Conversion in C using For

I am not able to convert from decimal to binary in C.Everytime I get a output which is one less than the desired output.For ex.:5 should be 101 but shows up as 100 or 4 should be 100 but shows up as 99.
#include<stdio.h>
#include<math.h>
void main() {
int a,b=0;
int n;
printf("Enter a Decimal Number\n");
scanf("%d",&n);
for(int i=0;n>0;i++) {
a=n%2;
n=n/2;
b=b+(pow(10,i)*a);
}
printf("%d",b);
}
My output is always one less than the correct answer and I dont know why.It fixes the problem if take b as 1 instead of 0 in the beginning but i dont know why.Please Help.I have just started C a few days ago.
pow is a floating-point function; it takes a double argument and returns a double value. In the C implementation you are using, pow is badly implemented. It does not always produce a correct result even when the correct result is exactly representable. Stop using it for integer arithmetic.
Rewrite the code to compute the desired power of ten using integer arithmetic.
Also, do not compute binary numerals by encoding them a decimal within a int type. It is wasteful and quickly runs into bounds of the type. Use either bits within an unsigned type or an array of char. When scanf("%d",&n); executes, it converts the input string into binary and stores that in n. So n is already binary; you do not need to decode it. Use a loop to find its highest set bit. Then use another loop to print each bit from that position down to the least significant bit.
This code seems fine. I quickly tested it on an online compiler and it seems to be working okay.
I am very sure it has to do with different versions of compilers.
compiler which I tested your code in: https://www.onlinegdb.com/online_c_compiler
Edit:
pow() function is not reliable when used with integers since the integer you pass into it as parameter is implicitly converted into data type of double and returns double as output. When you stuff this value into the integer again, it drops the decimal values. Some compilers seem to produce "correct" result with their version of pow() while some don't.
Instead, you can use a different approach to solve your decimal to binary conversion without errors in general use:
#include<stdio.h>
void main() {
int remainder,result = 0,multiplier = 1;
int input;
printf("Enter a Decimal Number\n");
scanf("%d",&input);
while(input){
remainder = input%2;
result = remainder*multiplier + result;
multiplier*=10;
input/=2;
}
printf("The binary version of the decimal value is: %d",result);
}

Expected value not obtained: why? [duplicate]

This question already has answers here:
printf specify integer format string for float
(7 answers)
Closed 5 years ago.
I wrote this very simple and short code, but it doesn't work: when I compile and execute the returned value from the function calculateCharges() is 0 when I'm expecting 2.
Can anybody explain why, please?
#include <stdio.h>
#include <stdlib.h>
float calculateCharges(float timeIn);
int main()
{
printf("%d", calculateCharges(3.0));
return 0;
}
float calculateCharges(float timeIn)
{
float Total;
if(timeIn <= 3.0)
Total = 2.0;
return Total;
}
There are at least three problems here, two of which should be easily noticeable if you enable compiler warnings (-Wall command-line option), and which lead to undefined behavior.
One is wrong format specifier in your printf statement. You're printing a floating point value wirh %d, the format specifier for signed integer. The correct specifier is %f.
The other is using uninitialized value. The variable Total is potentially uninitialized if the if statement in your function isn't gone through, and the behavior of such usage is undefined.
From my point of view, it's likely the wrong format specifier that caused the wrong output. But it's also recommended that you fix the second problem described above.
The third problem has to do with floating point precision. Casting values between float and double may not be a safe round-trip operation.
Your 3.0 double constant is cast to float when passed to calculateCharges(). That value is then cast up to a double in the timeIn <= 3.0 comparison (to match the type of 3.0).
It's probably okay with a value like 3.0 but it's not safe in the general case. See, for example, this piece of code which exhibits the problem.
#include <stdio.h>
#define EPI 2.71828182846314159265359
void checkDouble(double x) {
printf("double %s\n", (x == EPI) ? "okay" : "bad");
}
void checkFloat(float x) {
printf("float %s\n", (x == EPI) ? "okay" : "bad");
}
int main(void) {
checkFloat(EPI);
checkDouble(EPI);
return 0;
}
You can see from the output that treating it as double always is okay but not so when you cast to float and lose precision:
float bad
double okay
Of course, the problem goes away if you ensure you always use and check against the correct constant types, such as by using 3.0F.
%d will print integers.
Total is a float, so it will not work.
You must use the proper specifier for a float.
(You should research that yourself, rather than have us give you the answer)

Pow function returning wrong result

When I use the pow() function, sometimes the results are off by one. For example, this code produces 124, but I know that 5³ should be 125.
#include<stdio.h>
#include<math.h>
int main(){
int i = pow(5, 3);
printf("%d", i);
}
Why is the result wrong?
Your problem is that you are mixing integer variables with floating point math. My bet is that the result of 5^3 is something like 124.999999 due to rounding problems and when cast into integer variable get floored to 124.
There are 3 ways to deal with this:
more safely mix floating math and integers
int x=5,y=3,z;
z=floor(pow(x,y)+0.5);
// or
z=round(pow(x,y));
but using this will always present a possible risk of rounding errors affecting the result especially for higher exponents.
compute on floating variables only
so replace int with float or double. This is a bit safer than #1 but still in some cases is this not usable (depends on the task). and may need occasional floor,ceil,round along the way to get the wanted result correctly.
Use integer math only
This is the safest way (unless you cross the int limit). The pow can be computed on integer math relatively easily see:
Power by squaring for negative exponents
pow(x, y) is most likely implemented as exp(y * log(x)): modern CPUs can evaluate exp and log in a couple of flicks of the wrist.
Although adequate for many scientific applications, when truncating the result to an integer, the result can be off for even trivial arguments. That's what is happening here.
Your best bet is to roll your own version of pow for integer arguments; i.e. find one from a good library. As a starting point, see The most efficient way to implement an integer based power function pow(int, int)
Use Float Data Type
#include <stdio.h>
#include <math.h>
int main()
{
float x=2;
float y=2;
float p= pow(x,y);
printf("%f",p);
return 0;
}
You can use this function instead of pow:
long long int Pow(long long int base, unsigned int exp)
{
if (exp > 0)
return base * Pow(base, exp-1);
return 1;
}

Using round() function in c

I'm a bit confused about the round() function in C.
First of all, man says:
SYNOPSIS
#include <math.h>
double round(double x);
RETURN VALUE
These functions return the rounded integer value.
If x is integral, +0, -0, NaN, or infinite, x itself is returned.
The return value is a double / float or an int?
In second place, I've created a function that first rounds, then casts to int. Latter on my code I use it as a mean to compare doubles
int tointn(double in,int n)
{
int i = 0;
i = (int)round(in*pow(10,n));
return i;
}
This function apparently isn't stable throughout my tests. Is there redundancy here? Well... I'm not looking only for an answer, but a better understanding on the subject.
The wording in the man-page is meant to be read literally, that is in its mathematical sense. The wording "x is integral" means that x is an element of Z, not that x has the data type int.
Casting a double to int can be dangerous because the maximum arbitrary integral value a double can hold is 2^52 (assuming an IEEE 754 conforming binary64 ), the maximum value an int can hold might be smaller (it is mostly 32 bit on 32-bit architectures and also 32-bit on some 64-bit architectures).
If you need only powers of ten you can test it with this little program yourself:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(){
int i;
for(i = 0;i < 26;i++){
printf("%d:\t%.2f\t%d\n",i, pow(10,i), (int)pow(10,i));
}
exit(EXIT_SUCCESS);
}
Instead of casting you should use the functions that return a proper integral data type like e.g.: lround(3).
here is an excerpt from the man page.
#include <math.h>
double round(double x);
float roundf(float x);
long double roundl(long double x);
notice: the returned value is NEVER a integer. However, the fractional part of the returned value is set to 0.
notice: depending on exactly which function is called will determine the type of the returned value.
Here is an excerpt from the man page about which way the rounding will be done:
These functions round x to the nearest integer, but round halfway cases
away from zero (regardless of the current rounding direction, see
fenv(3)), instead of to the nearest even integer like rint(3).
For example, round(0.5) is 1.0, and round(-0.5) is -1.0.
If you want a long integer to be returned then please use lround:
long int tolongint(double in)
{
return lround(in));
}
For details please see lround which is available as of the C++ 11 standard.

Why does casting to int not floor all doubles in C

Given the C code:
#include <math.h>
#include <stdio.h>
int main(){
int i;
double f=log(2.0)/log(pow(2.0,1.0/2.0));
printf("double=%f\n",f);
printf("int=%d\n",(int) f);
}
I get the output:
double=2.000000
int=1
f is apparently at least 2.0. Why is the cast value not 2?
Because the value of the double was less than 2
double=1.99999999999999978
int=1
Try it but this time add some precision
#include <math.h>
#include <stdio.h>
int main(){
int i;
double f=log(2.0)/log(pow(2.0,1.0/2.0));
printf("double=%0.17f\n",f);
printf("int=%d\n",(int) f);
}
Confusing as hell the first time you experience it. Now, if you try this
#include <math.h>
#include <stdio.h>
int main(){
int i;
double f=log(2.0)/log(pow(2.0,1.0/2.0));
printf("double=%0.17f\n",f);
printf("int=%d\n",(int) f);
printf("int=%d\n", (int)round(f));
}
It will correctly round the value. If you look in the man page (on a mac at least) you'll see the following comment...
round, lround, llround -- round to integral value, regardless of rounding direction
What do they mean by direction, it's all specified in IEEE 754. If you check the different ways to round to an integer... floor is mentioned as rounding towards -ve infinity which is in this case was towards 1 :)
Floating point types are unable to represent some numbers exactly. Even though mathematically, the calculation should be exactly 2, with IEEE754 floating points, the result turns out to be slightly less than 2. For more information see this question.
If you increase the precision of your output by specifying %.20f instead of just %f, you will see that the number is not exactly 2, and that when printing with less accuracy, the result is simply rounded.
When converting to an int however, the full accuracy of the floating point type is used, and since it comes to just under 2, the result when converting to an integer is 1.
Integer does not take a rounded up value but makes a truncation. So, if f is equal to 1.999999999999[..]9, the int value will be 1.
Also, as the double wants to be the more accurate possible, he will take a rounded up value considering the number of characters he can show, which is 2.000000.

Resources