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
Related
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 program here that is supposed to sum up the series
1+1/2+1/3+1/4... etc
The only user entry is to enter how many times you want this sum to run for.
However, I keep getting the sum one.
#include <stdio.h>
int main(void)
{
int b,x; /* b is number of times program runs and x is the count*/
float sum;
printf("Enter the number of times you want series to run.\n");
scanf("%d", &b);
printf("x sum\n");
for(x=1,sum=0;x<b+1;x++)
{
printf("%d %9.3f\n",x, (sum +=(float)(1/x)));
}
return 0;
}
I don't quite get why it isn't working. As you can see, I did tell it to print x and when it did, x was incrementing correctly.The sum just kept adding up to one.
You have misplaced parentheses so you're doing integer division for 1/x and getting 0 for any value of x > 1.
I suggest you change:
printf("%d %9.3f\n",x, (sum +=(float)(1/x)));
to:
printf("%d %9.3f\n",x, (sum += 1.0f/x));
Two problems: one dull, one interesting.
1) 1 / x will be imprecise since 1 and x are both integral types and so the computation will be done in integer arithmetic. All the cast does is convert the resultant integral type to floating point. To resolve this, write 1.0 / x. Then 'x' is promoted to floating point prior to the division.
2) You should reverse the order of the for loop:
sum = 0.0;
for(x = b; x >= 1; --x)
(I've also moved the initialisation or sum from the for loop as sum = 0 is an expression of type float but x = b is an expression of type int so you ought not use the comma operator as they have different data types.)
The reason is subtle: you should only add floating points of similar magnitude. Doing the loop my way means the smaller values are added first.
The effect will be noticeable for high values of b; try it. Your original way will always understate the sum.
The problem is integer division when you do 1/x, which always result in 0 as long as x is greater than 1. Even it you later convert this to a float, the "damage" is already done. An easy fix would be to change the division to 1.0f/x.
Since you have declared x as an int, (1/x) returns 1 when x is 1 and 0 for x>1. So, sum remains 1. So you get the same result.
So, change (1/x) to 1.0f/x, so that the result is returned as a float
Here you are computing 1/x in which the fractional value is truncated. Converting it into float after the original value has been truncated doesn't make sense.
So change this to:-
printf("%d %9.3f\n",x, (sum +=(float)(1/x)));
to
printf("%d %9.3f\n",x, (sum += 1.0f/x));
The expression (1/x) will always be integer division. For the first run this will be 1/1 giving you 1. However, next time round it will be 1/2 which is 0. Basically for 1/x where x>1 the answer will be zero.
To get around this write the expression as 1.0/x which will cause x to be promoted to a double, giving you double division.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C compiler bug (floating point arithmetic)?
I've got two doubles which I can guarantee are exactly equal to 150 decimal places - ie. the following code:
printf("***current line time is %5.150lf\n", current_line->time);
printf("***time for comparison is %5.150lf\n", (last_stage_four_print_time + FIVE_MINUTES_IN_DAYS));
...returns:
***current line time is 39346.526736111096397507935762405395507812500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
***time for comparison is 39346.526736111096397507935762405395507812500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
FIVE_MINUTES_IN_DAYS is #defined, and current_line->time and last_stage_four_print_time are both doubles.
My problem is that the next line of my debugging code:
printf("if condition is %d\n", (current_line->time >= (last_stage_four_print_time + FIVE_MINUTES_IN_DAYS)));
returns the following:
if condition is 0
Can anyone tell me what's going on here? I am aware of the non-decimal/inexact nature of floats and doubles but these are not subject to any error at all (the original figures have all been read with sscanf or #defined and are all specified to 10 decimal places).
EDIT: My mistake was assuming that printf-ing the doubles accurately represented them in memory, which was wrong because one value is being calculated on-the-fly. Declaring (last_stage_four_print_time + FIVE_MINUTES_IN_DAYS) as threshold_time and using that instead fixed the problem. I will make sure to use an epsilon for my comparisons - I knew that was the way to go, I was just confused as to why these values which I (incorrectly) thought looked the same were apparently inequal.
Floats certainly are not accurate to 150 significant digits, so I 'm not sure what conclusion can be drawn from the "visual" comparison (if any).
On the other hand, the values are obviously not bit-identical (and how could they be, since one of them is calculated on the spot with addition?). So it's not really clear why the behavior you see is unexpected.
Don't ever compare floats like that, just do the standard comparison of difference vs epsilon.
Read about floating point representation (particularly http://en.wikipedia.org/wiki/IEEE_754-2008). Try printing the actual contents of the bytes containing the doubles as hexadecimal and they won't match bit for bit.
The proper comparison for floats is in Knuth (Seminumerical algorithms). Simply (replace bool with int and float with double, true with 1):
bool almostEqual(float x, float y, float epsilon)
{
if (x == 0.0 && y == 0.0) {
return true;
}
if (fabs(x) > fabs(y)) {
return fabs((x - y) / x) < epsilon;
} else {
return fabs((x - y) / y) < epsilon;
}
}
You should always use an EPSILON value for comparison of floats and doubles to check for equality. Even though it looks the same the internal representation is not guaranteed to match because of the way these types of numbers are represented in binary.
You can do something like
#define EPSILON 0.00001
...
if (fabs(a - b) <= EPSILON) return 1; // they are equal
return 0;
Jesus is right about how to solve this.
As for why... in one case you read in a constant value, in the other case you perform an addition operation. Even if the printed output is exactly the same, the binary representation can be slightly different.
Try inspecting the memory backing the two double's and see if any bits are different (there will be differences).
For a comprehensive treatment, I recommend
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
In general you shouldn't use == to compare floats or doubles. You should instead check that the difference is smaller than some small number.
double second_number = last_stage_four_print_time + FIVE_MINUTES_IN_DAYS;
if (fabs(current_line->time - second_number) < 0.001 || current_line->time > second_number){
// your comparison code
}
First, doubles have just 15-16 decimal places (log_2 of 52 bit matissa).
Second, if you want to compare, use the already mentioned epsilon.
Thirdly, for debugging, print the hex value.
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.
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).