int n,m;
float S,K,R,L,dr,dz;
S=4.0f;
K=2.0f;
R=1.0f;
L=2.0f;
dr=0.01f;
dz=0.1f;
n=int((R/dr)+1);
m=int((L/dz)+1);
printf("%d\t%d\t",n,m);
for this iam getting 10,20 grid points but actually the value should be 11,21 for n,m rply and for dr=0.01 its printing n=101 except this all other values of 'dr' it printing one value less like for dr=0.1 n=10 ,dr=0.001 n=1000 but actual value is 1001.please kindly explain me sir a have been trying it since one month still i didnt get the correct answer..
It's not completely clear to me what your question is, but you seem to be confused as to why the value of n is printed as 101. At the risk of pointing out the obvious, what you have in a purely mathematical expression is:
n = (1.0 / .01) + 1
1 divided by .01 equals 100. So even eliminating the possibilities of floating point error, then the answer of 101 is correct. The value of 20 being printed (rather than the "expected" 21) because of floating point error. You can see this more clearly if you add this statement:
printf( "%.15f\n", L / dz );
On my machine, it prints this:
19.999999701976780
The cast to int results in computing the floor of the value (20.999... ends up as 20 when cast to the integer value).
Related
This question already has answers here:
Why are floating point numbers inaccurate?
(5 answers)
Closed 5 years ago.
I am a beginner and this is (a simplified version of) part of a code I am writing:
1.prompt user to input a number (float dollar amount), lets say user will only key in amount which are multiples of 0.05 ;
2.calculate the (int)number of nickels in that dollar amount.
int main(void)
{
float amount = 0;
printf("$ ");
amount = get_float();
int n = 0;
while ((amount - 0.05) >= 0)
{
amount -= 0.05;
n ++;
}
printf("%i nickels\n", n);
}
It works for any amount <=0.3 or >=1.2 (so $2 has 40 nickels, and $0.30 has 6 nickels);
but one nickel less for any amount between/including 0.35 and 1.15 (so $0.35 has 6 nickels, and $1 has 19 nickels)
I did step by step printing, and it turns out that for any amount between 0.35 and 1.15, the program stops at the last 0.050000, instead of going back to the loop and loop it one last time.
What went wrong? Please help... Thanks so much for your time!
You are hitting up against floating point rounding.
Floating points are never exactly accurate, try calculating
printf("one third 'ish' = %6.20lf\n", (double) 1.0/ (double) 3.0);
Look at the answer, it's not quite accurate. :)
Your best bet is to accept the input, convert it to an integer (ie, cents) by multiplying by 100, removing any decimals using round() and assigning to a long.
#include <math.h> // to get the round() function
.
.
.
long amountInCents = round(amount * 100);
Then, change your code to compare against 5 cents, not $0.05, and to reduce by 5 cents, not $0.05
This way, you get rid of all 'rounding' issues.
EDIT: cmaster showed me that using floor() didn't work, using $0.57 as input, when using 'double' variables (not float), $0.57 converted to (long) 56! He supplied code and I couldn't believe my eyes!
The is no bug in your code in the strictest sense as the underlying reasoning is correct; however note that the value 0.35 cannot be represented exactly in the float datatype, the same holds for 0.05; as the division (what basically is the sematics of the code in the question) is implemented via repeated subtraction, the error caused by the inability to exactly represent the desired values accumulates. The result is that the number of subtractions is different from the analytically expected result, as the termination condition is reached too soon. The float datatype is not suitable for financial calculations, even in such a very small everyday example.
This is terrible, but it is a matter of fact.
I found a fix. This is working
enter code here
while ((amount - 0.0499) >= 0)
{
amount -= 0.05;
n ++;
}
while scanning .35 amount as float the actual amount value is 0.3499
I saw this code on Exam: the question is how many times this string will be printed.
I thought first it will be 10 times but this is wrong.
Can someone tell me why my answer is wrong.
This is part of a code in the C language.
for (float x = 100000001.0f; x <= 100000010.0f; x += 1.0f) {
printf("lbc");
}
Assuming x is a 32 bit floating point:
Floating point values have a limited resolution. 100000001 is 1*10^8 so you lose your 1 at the end. If you would add 1, it again gets lost because the next float value is 1.00000008*10^8. You can add as many 1s as you like the result will always be the same.
That is the reason why your code is an endless loop.
float x = 100000001.0f;
will initialize x with the nearest representable float, which is 100000000. Adding 1 to this value will lead to the same value.
If you print the value of x in the loop you will see what happen: http://ideone.com/3FJGTz
i'm trying to understand why in the following situation i don't get an overflow:
double x = 1.7976931348623157E+308; //this is the max value of double
x = x + 0.5;
When checking the value of x after adding 0.5 i still get the same result.
Anyone?
Generally if you want to add a value to a double x the added value should be within the precision range for it to change the value at all.
For a double you get a precision of ~16 digits. So, if the added value is less than (x/1E+16), then there will be no change in the result.
With a little trial and error, in your case, adding a value of 1E+292, to the given double, gives a result of +INF.
double x = 1.7976931348623157E+308; //this is the max value of double
x = x + 1E+292;
printf ("\nx = %lf",x);
Result
x = 1.#INF00
Consider the analogy with exponent notation.
Suppose you are allowed 4 significant digits, so the number 1234000.0 will be represented by 1.234e6.
Now try adding 0.5 which should be 1234000.5.
Even if the intermediate buffer is big enough to hold that significance, its representation within the proscribed limit is still 1.234e6.
But if the intermediate buffer can hold, say, only 7 digits, the aligned values to add are
1234000
0
-------
1234000
so the 0.5 loses its significance even before the addition is performed. In the case of double you can be quite sure the intermediate buffer cannot hold 308 digits equivalent.
I have a homework in C. We have to write our own asin() function with Taylor method, and we can't use math.h
It works fine, but once I put higher count of iterations(int i), it returns NaN(Not a Number), and when I use low count of i, the number is not exact. Can anyone help me with this?
double my_asin(double x)
{
int i = 0;
double vypocet = x;
double y = vypocet;
for(i=1;i<=10000;i++)
{
vypocet*=((x*x)*(2*i-1)*(2*i-1))/((2*i)*(2*i+1));
y+=vypocet;
}
printf("my_asin = %.10e\n", y);
return y;
}
EDIT: Thank you all! finished it :)
Two things are required for your answer :
Regarding maths : The series expansion you are coding is a sin inverse (arcsin) and expecting an output in radian.
sin^(-1)x=x+1/6x^3+3/(40)x^5+5/(112)x^7+(35)/(1152)x^9+... . As you can see this is an expansion which is monotonically increasing and expecting value (input) between [-1,1] only. When you plug in large values e.g. 10 you are bound to get results you don't expect.So , plug in correct values. I guess, put correct values [-1,1] when calling the function my_asin() and your code would work fine FOR THE number of ITERATIONS YOU HAVE NOW.
e.g 1.5146343691e+000 looks fine for 90 degrees or pi/2 or my_asin(1).
2 .Regarding Floating Point (double i.e. single prrecision floating point ):They cant represent all the numbers on the real line, their range is a subset of R.And when there is a number that can't be represented correctly by their 32 bits encoding (IEEE 754) you will get error in result.
Number as simple as 0.1 cant be represented exactly using floating point.
Check these pages for FP Errors and FP Exceptions :
http://www.gnu.org/software/libc/manual/html_node/Infinity-and-NaN.html
http://www.gnu.org/software/libc/manual/html_node/FP-Exceptions.html#FP-Exceptions
Beginner here.
Why is this an endless loop ?
for (p = 0; p < 5; p += 0.5)
{
printf("p=%2.2f\n",p);
}
You see an endless loop because your p is of an integral type (e.g. an int). No matter how many times you add 0.5 to an int, it would remain 0, because int truncates double/fp values assigned to it. In other words, it is equivalent to a loop where you add zero on each step.
If you make p a float or a double, your problem would go away.
EDIT (Suggested by Oli Charlesworth's comment)
It is worth noting that using floats and doubles to control loops is discouraged, because the results are not always as clean as in your example. Changing the step from 0.5 (which is 2 to the negative power of 1) to 0.1 (which is not an integral negative power of 2) would change the results that you see in a rather unexpected way.
If you need to iterate by a non-integer step, you should consider using this simple pattern:
// Loop is controlled by an integer counter
for (int i = 0 ; i != 10 ; i++) {
// FP value is calculated by multiplying the counter by the intended step:
double p = i * 0.5;
// p is between 0 and 4.5, inclusive
}
I think it depends on how p is declared. If it's an integer type, p will always be 0 (because the result of 0 + 0.5 will be truncated to 0 every time) so the for will never stop.
a type conversion problem, float/double lost precision when assigned to an integer type.
P.S. It is really a very bad idea to use float/double in condition test. Not all floating point numbers in computers are accurate.
If p is a float or a double, there's nothing wrong with the code, and the loop will terminate.
If p is integer, the behaviour of the code is undefined since the format specifier in printf() is wrong.
when you add a double constant to integer variable, the double constant "becomes" integer. 0.5 becomes just 0. So you add 0 to p.