I'm starting coding in C and I was doing an exercise, but saw a miscalculation testing this code:
int main(){
int number;
int square;
printf("Pick a number: ");
scanf("%d",&number);
while(number<=0)
{
printf("ERROR: The number MUST be greater than zero\nPick a number greater than zero: ");
scanf("%d",&number);
}
square = pow(number,2);
printf("\nThe square of the number is: %d\n\n",square);
system("pause");
return 0;}
now... everything works just fine, but when I use the number "5", it shows the result "24", when it should be "25". anyone knows why this happen?
pow takes double arguments and returns a double. So you're getting a rounding error.
Because in C standard library, pow is defined as a function taking double arguments and returning a double value. Even if nothing is required by the standard concerning the implementation, common implementations use (more or less) the following formula: pow(x, y) = exp(y * log(x)). That means that even if you pass integer values, the internal operations will use non integer values, and rounding errors will occur.
That is what happens with your current implementation with 5. To make sure of it, just print the result as a double:
double dsq = pow(5, 2);
printf("%f", dsq);
dsq (in your implementation) should be slightly off and when rounded you get 24
The function pow() takes a double value as an input parameter and returns a double also, as it is defined in the C standard library. However, the variable you pass to (number) is an int variable. This results in a rounding error as the compiler uses a non-integral value for the calculation process.
To get around this error, declare number with type double instead of int:
double number;
That should sort the rounding issue.
Hum I think you should cast pow in int :
square = (int)pow(number,2);
Related
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);
}
I run two same code. But it shows different answer.
Code 1:
#include<stdio.h>
int main(){
float far = 98.6;
printf("%f", (far-32)*5/9);
return 0;
}
Code 2:
#include<stdio.h>
int main(){
float far = 98.6;
float cel;
cel = (far-32)*5/9;
printf("%f", cel);
return 0;
}
First code gives 36.99999 as output and second code gives 37.00000 as output.
Research FLT_EVAL_METHOD. This reports the intermediate floating-point math allowed.
printf("%d\n", FLT_EVAL_METHOD);
When this is non-zero, the 2 codes may have different output as printf("%f", (far-32)*5/9); can print the result of (far-32)*5/9 using double or float math.
In the 2nd case, (far-32)*5/9); is performed user float or double and then saved as a float and then printed. Its promotion to a double as part of a printf() ... argument does not affect the value.
For deeper understanding, print far, cel, (far-32)*5/9 with "%a" and "%.17g" for greater detail.
In both cases, far is the float value 0x1.8a6666p+6 or 98.599998474121094...
As I see it the first used double math in printf("%f", (far-32)*5/9); and the second used double math too, yet rounded to a float result from cel = (far-32)*5/9;. To be certain we need to see the intermediate results as suggested above.
Avoid double constants with float objects. It sometimes makes a difference.
// float far = 98.6;
float far = 98.6f;
Use double objects as a default. Save float for select speed/space cases. #Some programmer dude.
The difference lies in the types used and the printf call.
Variable-argument functions like printf will promote arguments of smaller types. So for example a float argument will be promoted to double.
The type double have much higher precision than float.
Since in the first program you do the calculation as part of the actual printf call, not storing the result in a variable using less precision, the compiler might perform the whole calculation using double and increasing the precision. Precision that will be lost when you store the result in cel in the second example.
Unless you have very specific requirements, you should generally always use double for all your floating-point variables and values and calculations.
I try to solve a math problem and my output sensitivity has a little different such as 0.07. And then I compare pow() and powf() in my code and I see this sensitivity. The code as follows:
int main()
{
int terms, sign=-1;
double x, operation=0.0;
printf("Please enter the number of terms : ");
scanf_s("%d", &terms);
while (terms <= 0)
{
printf("Please re-enter the number of terms :");
scanf_s("%d", &terms);
}
printf("Please enter a value for x :");
scanf_s("%lf", &x);
for (int i = 1; i <= terms; i++)
{
sign = sign * (-1);
operation = operation + sign * powf(x + i / 10.0, (2 * i) - 1) / (2 * i);
}
printf("The result is : %.2lf\n", operation);
system("pause");
return 0;
}
Sample:
terms : 10
x : 1.1
output : `-59783.61` with `powf`
output : `-59783.67` with `pow`
What is the difference between to these functions?
pow operates on doubles. powf operates on floats. This is a fairly standard notation in C, where the base name of a function will be for operands (and return values) of the default type (like int and double), while prefixed and suffixed versions are for other types (like long, float, etc). Here is a reference: http://pubs.opengroup.org/onlinepubs/9699919799/.
This difference in data types fully explains the differences you see in your result.
doubles contain 53 bits of precision in the mantissa, which translates to ~16 decimal digits of precision. This exceeds the precision with which you display your result, so is probably accurate enough for your purposes.
floats, on the other hand, have only 24 bits in the mantissa, which translates to ~7 decimal digits. Any combination of operations will cause roundoff errors do creep in almost immediately to within your display precision.
The C language did not have "generic functions" until C11. Instead, there are different functions in the standard library for different data types.
The *f functions of <math.h> operate on single-precision floating point numbers (floats using single precision internally. double stands for ... double precision. Always use the non-f functions for double arguments.
As said here , pow takes a double, where powf takes a float rendering it much less precise.
powf returns and takes arguments of float.
pow returns double and takes arguments of double. If a float number is given as parameter, it is converted to double by the usual promotion rules.See here
The difference you are seeing in the result is due to the higher precision of double
The difference is :
float powf( float base, float exponent );
double pow( double base, double exponent );
DESCRIPTION in here
The pow functions compute base raised to the power of exponent.
While running the following lines of code:
int i,a;
for(i=0;i<=4;i++)
{
a=pow(10,i);
printf("%d\t",a);
}
I was surprised to see the output, it comes out to be 1 10 99 1000 9999 instead of 1 10 100 1000 10000.
What could be the possible reason?
Note
If you think it's a floating point inaccuracy that in the above for loop when i = 2, the values stored in variable a is 99.
But if you write instead
a=pow(10,2);
now the value of a comes out to be 100. How is that possible?
You have set a to be an int. pow() generates a floating point number, that in SOME cases may be just a hair less than 100 or 10000 (as we see here.)
Then you stuff that into the integer, which TRUNCATES to an integer. So you lose that fractional part. Oops. If you really needed an integer result, round may be a better way to do that operation.
Be careful even there, as for large enough powers, the error may actually be large enough to still cause a failure, giving you something you don't expect. Remember that floating point numbers only carry so much precision.
The function pow() returns a double. You're assigning it to variable a, of type int. Doing that doesn't "round off" the floating point value, it truncates it. So pow() is returning something like 99.99999... for 10^2, and then you're just throwing away the .9999... part. Better to say a = round(pow(10, i)).
This is to do with floating point inaccuracy. Although you are passing in ints they are being implicitly converted to a floating point type since the pow function is only defined for floating point parameters.
Mathematically, the integer power of an integer is an integer.
In a good quality pow() routine this specific calculation should NOT produce any round-off errors. I ran your code on Eclipse/Microsoft C and got the following output:
1 10 100 1000 10000
This test does NOT indicate if Microsoft is using floats and rounding or if they are detecting the type of your numbers and choosing the appropriate method.
So, I ran the following code:
#include <stdio.h>
#include <math.h>
main ()
{
double i,a;
for(i=0.0; i <= 4.0 ;i++)
{
a=pow(10,i);
printf("%lf\t",a);
}
}
And got the following output:
1.000000 10.000000 100.000000 1000.000000 10000.000000
No one spelt out how to actually do it correctly - instead of pow function, just have a variable that tracks the current power:
int i, a, power;
for (i = 0, a = 1; i <= 4; i++, a *= 10) {
printf("%d\t",a);
}
This continuing multiplication by ten is guaranteed to give you the correct answer, and quite OK (and much better than pow, even if it were giving the correct results) for tasks like converting decimal strings into integers.
I have a very simple C program.
int main(void){
double sum = 1/2;
printf("%d\n", sum);
return 0;
}
Why does it return a number like "-2030243223"?
And why does this number change every time I run the program?
I've tried using int's and float's but I can't seem to get the output to be 0.5!?
Use %f to print a double, not %d. The latter causes undefined behavior.
Also the expression 1/2 uses integer division which yields 0, so to get .5, use 1/2. (note trailing period).
Finally, to actually get .5 instead of something like 0.500000, specify the precision:
printf("%.1f\n", sum);
You're passing an IEEE floating-point number to printf, but telling it it's an integer.
Change
printf("%d\n", sum);
to
printf("%f\n", sum);
As noted in other comments, you probably also want to do floating-point division rather than integer division. 1/2 is zero; you're dividing two integers, so the result is an integer (yes, even though you're about to assign it into a floating-point variable -- each expression's type is determined in isolation) and it has to discard the remainder. You probably want 1.0/2 instead; if either term is a float, then the result is a float, so you'll get 0.5.
You're trying to print a double to an Integer. (%d).
Even though they both are numbers, internally there are huge differences, for example, memory ones.
You're trying to print a double as an int. Try using:
printf("%g\n");
Also, you will want to make you initial division 1.0/2.0 or else you will get 0.
Try this:
int main(void){
double sum = 1.0/2.0;
printf("%10.3f\n", sum);
return 0;
}
There is a couple of issues with your code
int main(void){
// you need to divide a double by a double, not two ints
double sum = 1.0/2.0;
// %d is for int, not doubles. You use %f in the case of printing a double
printf("%f\n", sum);
return 0;
}
Now if you really want to print the variable as an int, you can cast the variable sum as an int by doing printf("%d\n", (int)sum);, but you'll have a rounding issue.
Try the following:
printf("%f\n", sum);
%d is a placeholder for integer, maybe the address of sum has been printed out^^
The bad format can't be the whole answer, because:
With OP's code, the double should be zero, stored as 0x0000000000000000, which couldn't show as "-2030243223" (0x86FCF269).
OP says this value changes all the time.
So there must be something else, such as the fact that the header is missing: I guess the compiler doesn't know printf is a variadic function, and tries to pass the argument through floating-point registers.
printf, being a variadic function, probably attempts to read its input value from the stack, hence garbage.