I was recently asked this question in a programming test. I can't seem to understand why I am getting the answer '1'. I am a beginner in the C programming language.
Here is my code:
#include<stdio.h>
int main()
{
float c = 0;
int n, i = 1;
printf("Enter the number here: ");
n = getchar();
while (i <= 2*n - 1)
{
c = c + (1/i);
i = i + 2;
}
printf("%f", c);
}
I have already tried using a for loop, but the answer remains the same. Any help would be appreciated!
The problem in your code lies on this line:
c = c + (1/i);
Here, the operation performed inside the parentheses is integer division! So, when i has any value greater than 1, the result will be zero. This zero is then converted to a float value.
To force the compiler to use floating point division, use this:
c = c + (1.0/i);
I agree with Adrian's answer.
Another issue is because of the way floating point numbers are represented in a system when they are added in arbitrary order, precision can be lost.
To have maximum precision, floating point numbers should be added from smallest first to largest last.
Related
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;
}
I have a homework assignment in basic C that is asking me to calculate certain expressions and then check my answers in a program. I can't seem to get any of these answers correct by my own calculations...
They want me to solve math problems using these variables:
int a = 2;
double b = 4.7;
int c = 3;
double d = 4.2;
Here's an example question:
int answer1 = b+a/c-d;
I understand that since it has an int operand then all the variables convert to an integer, so it should look something like this I think:
(4+2)/(3-4)
I got -6 as my answer when doing it by hand, but when I input it as code it gives me an answer of 0. Can anyone explain this? Am I doing the order of operations wrong? I simply don't understand how the computer gets 0 out of that. This is the easiest question in my homework and I don't have a clue. Please help!
Your expression
b+a/c-d
is the same as
b + (a/c) - d
Since both a and c are integers, then the quotient a/c is computed using integer division. That gives 2/3 = 0. So then you have:
b - d
This is calculated using floating point since b and d are double. The result is 0.5, which when assigned to the result int, is truncated to 0.
Your orders of operations is a bit off:
int answer1 = b+(a/c)-d;
int tmp1 = a/c; ---> 2/3 --> 0
int answer1 = 4.7 + 0 - 4.2 ----> 0.5 --> 0
http://www.cplusplus.com/doc/tutorial/typecasting/
I have this question:
We claim that it is unsafe to use equality testing with floating point numbers because the arithmetic operations introduce rounding errors which mean that two numbers which ought to be equal are not.
For this program, you should pick a number N, and write a program to show for which of the integers x between 1 and 1000 the equality
(x+1)/N = (x/N) + (1/N) fails
#include <stdio.h>
int main () {
int x;
float N = 50;
for (x=0; x<1001; x++) {
if ((x+1)/N != (x/N) + (1/N))
{
printf("%i\n",x);
}
}
}
Is this correct?
Thanks.
Your program is wrong. It should start with x=1 instead of x=0.
But beside that, you should pick two examples (one that has been printed by the program and one that hasn’t) and calculate them by hand. With just pen and paper and the IEEE 754-1985 rules. Then print both sides of the equation and compare them to your hand-computed results.
I edited a C program for my assignment, previously there wasn't typecasting and the iteration stopped at i=1, now with the typecasting it stops at i=6.
Any ideas why? Thanks in advance!
int main(void)
{
int i = 0;
double d = 0.0;
while ( (i == (int) (d * 10)) && (i < 10) )
{
i = i + 1;
d = (double) (d + 0.1);
printf("%d %lf\n", i, d);
}
printf("%d %lf\n", i, d);
getch();
return 0;
}
Floating point arithmetic is inexact. The value 0.1 is not exactly representable in binary floating point. The recommended reading here is: What Every Computer Scientist Should Know About Floating-Point Arithmetic.
At some point in the program, d becomes slightly less than i/10 due to rounding error, and so your loop terminates.
In addition to the other answers, I'd like to answer the question why the loop terminates earlier with the condition i == (d * 10) than with i == (int) (d * 10).
In the first case, int value at the left side of == is promoted to double, so the inequality happens when the accumulated error in d*10 is either positive or negative (e.g. 0.999999 or 1.000001).
In the 2nd case, the right side is truncated to int, so the inequality happens only when the error is negative (e.g. 5.999999). Therefore, the 1st version would fail earlier.
As has been stated many times before, the reason this doesn't work is that binary floating point numbers cannot represent all decimal floating point binary numbers, it just isn't possible. To read more, check out this really great article:
What Every Programmer Should Know About Floating-Point Arithmetic
Now, on the more practical side of things, when using floating point and comparing it to another number, you should almost always round the value or use an epsilon value, like this:
if (ABS(doubleValue - intValue) < 0.00001) // 0.00001 is a margin-of-error for floating point arithmetic
// the two numbers are even (or close to it)
I tried following code snippet and output is surprising me:
#include <stdio.h>
#include <math.h>
int main()
{
double num;
unsigned char ch;
ch = 19;
num = 1.0E+20 ;
num += ch * 1.0E+18;
printf("E18 = %lf \n",num);
printf("E18 = %e \n",num);
num = 11.0E+21 ;
num += ch * 1.0E+19;
printf("E19 = %lf <------\n",num);
printf("E19 = %e <------\n",num);
num = 11.0E+22 ;
num += ch * 1.0E+20;
printf("E20 = %lf\n",num);
printf("E20 = %e\n",num);
num = 11.0E+23 ;
num += ch * 1.0E+21;
printf("E21 = %lf\n",num);
printf("E21 = %e\n",num);
num = 11.0E+24 ;
num += ch * 1.0E+22;
printf("E22 = %lf <------\n",num);
printf("E22 = %e <------\n",num);
return 0;
}
The output of the program:
E18 = 119000000000000000000.000000
E18 = 1.190000e+20
E19 = 11190000000000000524288.000000 <------
E19 = 1.119000e+22 <------
E20 = 111900000000000001048576.000000
E20 = 1.119000e+23
E21 = 1119000000000000044040192.000000
E21 = 1.119000e+24
E22 = 11189999999999999366660096.000000 <------
E22 = 1.119000e+25 <------
Why the data corrupted when printed while in exponent form its OK
Because, you lose precision when the numbers grow big enough : http://en.wikipedia.org/wiki/Floating_point
The data is not corrupted; that's simply how floating point values work in today's computers. Think of a float as a fixed number of digits (the mantissa) and another number that indicates where the decimal point should be placed (the exponent). For the long and more accurate story, Wikipedia is a good start.
Since the number of digits of the mantissa is fixed, it cannot represent the tiny fraction that you're asking for here. Furthermore, because it's all in binary, decimal numbers cannot always be represented exactly.
The exponential notation simply rounds off the last few digits where the number is known to be inaccurate, hence your results.
Double/floating-point numbers lose precision as they get larger - in addition to the Wikipedia article Tuomas has posted, here's another good one:
http://www.yoda.arachsys.com/csharp/floatingpoint.html
It was targeted at .NET but the principle still applies.
Floating point data types use a finite number of bits to represent a certain range of numbers. However, there can be an infinite number of values between any two real numbers m and n. So, you sacrifice precision.
It looks alright in exponent form since not all digits are being printed.
As a test, try printing the value 0.2 with about 10 decimal places and you will see that the value stored is more like 0.1999999....
You are seeing the imprecision inherent in floating point.
Certain printf conversions are guaranteed to produce enough significant figures to uniquely identify the number being printed. This implies that if there is any imprecision, you will see it. Conversely, the default %e/%f representation hides the imprecision by rounding.
As far as I know, %a (hexadecimal floating point) is the only way to achieve this. According to the POSIX spec, %lf is defined to do the same thing as %f, that is,
l (ell) … has no effect on a following a , A , e , E , f , F , g , or G conversion specifier.
So this is technically a bug in your standard library.