This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 5 years ago.
What I am trying to do here is, I am taking a precision value (less than 1) and printing count of all the numbers of type 1/n (n is natural number) which are greater than or equal to the precision value (input).
#include <stdio.h>
int main(){
int i=1,terms=0;
float n;
printf("Enter precision value : ");
scanf("%f",&n);
while(i>0){
if ((1.0/i) >= n){
printf("%f\n",1.0/i);
sum = sum + (1.0/i);
terms++;
i++;
}
else
break;
}
printf("number of terms : %d\n",terms);
return 0;
}
But if I give input 0.1 than the count (output) is showing only 9. but it should show 10 (it is not including 1/10).
I was using a for loop before and I know that breaking a loop with an if-else statement is not the best thing.
That's just the way math works with limited precision. For example, say you're using six digits of decimal precision. The best you can do for one-third is 0.333333 and the best you can do for 2/3 is 0.666667, but then 2 * 1/3 will not equal 2/3. And 3 * 1/3 will not equal 1. But 1/3 + 2/3 will.
Just as 1/3 cannot be expressed exactly in decimal, 0.1 cannot be expressed exactly in binary. So testing for equivalence is not smart.
Related
This question already has answers here:
Why are floating point numbers inaccurate?
(5 answers)
Closed 3 months ago.
#include <stdio.h>
typedef struct ElapsedTime_struct {
int decadesVal;
int yearsVal;
} ElapsedTime;
ElapsedTime ConvertToDecadesAndYears(int totalYears) {
ElapsedTime tempVal;
tempVal.decadesVal = totalYears/10;
tempVal.yearsVal = (((double) totalYears/10) - tempVal.decadesVal) * 10;
return tempVal;
}
int main(void) {
ElapsedTime elapsedYears;
int totalYears;
scanf("%d", &totalYears);
elapsedYears = ConvertToDecadesAndYears(totalYears);
printf("%d decades and %d years\n", elapsedYears.decadesVal, elapsedYears.yearsVal);
return 0;
}
my logic is that if you take number of total years( 26) and divide the integer value by 10, you will get the number of decades. int (26/10) = 2
my logic for the number of years is that if you take the double value of 26/10, you will get 2.6000
then subtracting 2.6 - 2 (number of decades), you will get the decimal value for the number of years(0.6)
i then multiplied by 10 to get a whole value (6) so together its 2 decades and 6 years.
however when i try running the code for some inputs (34 total years) i am getting 3 decades and 3 years for some reason whereas i should get 3 decades and 4 years.
i am confused as to why this is happening.
Floating point math is inexact. Values such as 2.6 and 3.3 cannot be exactly represented in binary floating point. You instead end up with a value that is either slightly larger or slightly smaller.
The latter case is what you're seeing. 3.4 is stored as roughly 3.39999999999999991. Subtracting 3 from that and multiplying by 10 gives you 3.9999999999999991, then when you convert that to an int the fractional part is truncated giving you 3.
That being said, you don't need floating point operations here. You can instead use the modulus operator % to get the remainder when dividing by 10.
tempVal.yearsVal = totalYears%10;
This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 6 years ago.
I tried to sum some numbers in a for loop but it didn't go as I expected
float sum = 0;
int i;
printf("0.1+0.1=%f\n", 0.1 + 0.1);
for (i = 0; i<1000000; i++)
{
sum = sum + 0.1;
}
printf("the sum need to be 100000 \n");
printf("the real sum is:\n %f\n", sum);
system("PAUSE");
this program prints:
0.1+0.1=0.200000
the sum need to be 100000
the real sum is:
100958.343750
Press any key to continue . . .
can you explain please this strange result?
the international standard for floating point numbers does not have an exact representation for some decimal numbers.
http://en.wikipedia.org/wiki/IEEE_754
It is due to the way they are stored in memory, the way the mantissa and exponent are stored.
https://en.wikipedia.org/wiki/Floating_point
This is also the reason why you should never compare two float numbers even if they look "the same".
I still remember how surprised I was the fist time a simple code comparing two float numbers didn't work :) This alone would open a dedicated universe of discussions. It is very worth reading anyway:
http://floating-point-gui.de/errors/comparison/
The floating numbers are stored in memory as x*2^y where x is between 0 and 1 with some precision and y is integer and so they accurately don't represent most numbers, they represent numbers "close enough".
When you do this addition multiple times, the error is just more visible.
You can use double type for better accuracy.
This question already has answers here:
Why are floating point numbers inaccurate?
(5 answers)
Closed 8 years ago.
I have a simple C snippet as follows:
#include<stdio.h>
#include<conio.h>
int main()
{
float a=0.3,b=0.5
clrscr();
if(a==0.3)
{
printf("equal");
}
else
{
printf("unequal");
}
if(b==0.5)
{
printf("equal");
}
else
{
printf("unequal");
}
getch();
}
shows output as: unequal equal.
I understand this because computer takes 0.3 as 1/3 and as 0.333... is not equal to 0.33, it shows output unequal, while in 0.5 is precise number so it gives output as equal.
But now if I take float b=0.2 like this:
float b=0.2;
if(b==0.2)
{
printf("equal");
}
else
{
printf("unequal");
}
Then it also shows unequal as output! As 0.2 is 1/5 - precise value, it should give output equal.
Can anyone tell me if anything is wrong here?
Simplifying somewhat, floating point numbers are basically stored as a series of fractions of powers of 2. (1/2, 1/4, 1/8, 1/16, 1/32, 1/64, etc). If your number can be represented as the sum of some number of those, you are lucky -- for most numbers (1/3, 1/5, etc) you get a pretty close approximation. Comparing floating point numbers for exact equality is fraught with peril.
This question already has answers here:
Floating point inaccuracy examples
(7 answers)
C++ floating point precision [duplicate]
(5 answers)
Closed 8 years ago.
I found this code snippet on Page 174, A Book on C -Al Kelley, Ira Pohl .
int main()
{
int cnt=0; double sum=0.0,x;
for( x=0.0 ;x!= 9.9 ;x+=0.1)
{
sum=sum +x;
printf("cnt = %5d\n",cnt++);
}
return 0;
}
and it became a infinite loop as the book said it would. It didnt mention the precise reason except saying that it had to do with the accuracy of the machine.
I modified the code to check if
x=9.9
would ever become true, i.e. x was attaining 9.9 by adding the following lines
diff=x-9.9;
printf("cnt =10%d \a x =%10.10lf dif=%10.10lf \n",++cnt,x,diff);
and i got the following lines among the output
cnt =1098 x =9.7000000000 dif=-0.2000000000
cnt =1099 x =9.8000000000 dif=-0.1000000000
cnt =10100 x =9.9000000000 dif=-0.0000000000
cnt =10101 x =10.0000000000 dif=0.1000000000
cnt =10102 x =10.1000000000 dif=0.2000000000
if x is attaining the value 9.9 exactly , why is it still a infinite loop?
You are simply printing the number with too poor accuracy to notice that it isn't exact. Try something like this:
#include <stdio.h>
int main()
{
double d = 9.9;
if(d == 9.9)
{
printf("Equal!");
}
else
{
printf("Not equal! %.20f", d);
}
}
Output on my machine:
Not equal! 9.90000000000000035527
The book is likely trying to teach you to never use == or != operators to compare floating point variables. Also for the same reason, never use floats as loop iterators.
The problem is that most floating point implementation are based on IEEE 754. See http://en.wikipedia.org/wiki/IEEE_floating_point
The problem with this is, that numbers are builded with base 2 (binary formats).
The number 9.9 can never be build with base 2 excatly.
The "Numerical Computation Guide" by David Goldberg gves an exact statement about it:
Several different representations of real numbers have been proposed,
but by far the most widely used is the floating-point representation.
Floating-point representations have a base b (which is always assumed to
be even) and a precision p. If b = 10 and p = 3, then the number 0.1 is
represented as 1.00 × 10^-1. If b = 2 and p = 24, then the decimal
number 0.1 cannot be represented exactly, but is approximately
1.10011001100110011001101 × 2^-4.
You can safely assume two floating point numbers are never equal 'exactly' (unless one is a copy of the other).
Computer works on binary and floating point, in other words in base 2. Just like base 10, base 2 have numbers that it cannot build. For example, try to write the fraction 10/3 in base 10. You'll end up with infinite 3s. and in Binary, you cannot even write 0.1 (decimal) in binary, you'll also get a recurring pattern 0.0001100110011... (binary).
This video will do better to explain http://www.youtube.com/watch?v=PZRI1IfStY0
This question already has answers here:
How dangerous is it to compare floating point values?
(12 answers)
Closed 9 years ago.
Look at the output of this link(scroll down to see the output) to find out what I'm trying to accomplish
The problem is with the for loop on line number 9-11
for(i=0; i<=0.9; i+=0.1){
printf("%6.1f ",i);
}
I expected this to print values from 0.0 until 0.9 but it stops after printing 0.8, any idea why ??
Using float here is source of problem. Instead, do it with an int:
int i;
for(i = 0; i <= 10; i++)
printf("%6.1f ", (float)(i / 10.0));
Output:
0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
Ideally floating point should not be used for iteration, but if you want to know why change your code and see how.
for(float i=0; i<=0.9f; ){
i+=0.1f;
System.out.println(i);
}
Here is the result.
0.1
0.2
0.3
0.4
0.5
0.6
0.70000005
0.8000001
0.9000001
your 9th value exceeds 0.9.
Floating point arithmetic is inexact in computing. This is because of the way that a computer represents floating point values. Here's an excerpt from an MSDN article on the subject:
Every decimal integer can be exactly represented by a binary integer; however, this is not >true for fractional numbers. In fact, every number that is irrational in base 10 will also be >irrational in any system with a base smaller than 10.
For binary, in particular, only fractional numbers that can be represented in the form p/q, >where q is an integer power of 2, can be expressed exactly, with a finite number of bits.
Even common decimal fractions, such as decimal 0.0001, cannot be represented exactly in >binary. (0.0001 is a repeating binary fraction with a period of 104 bits!)
Link to the full article: https://support.microsoft.com/kb/42980
Floating point number cannot precisely represent decimals, so rounding errors accumulate:
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
float literal = 0.9;
float sum = 0;
for(int i = 0; i < 9; i++)
sum += 0.1;
cout << setprecision(10) << literal << ", " << sum << endl;
return 0;
}
Output:
0.8999999762, 0.9000000954
You loop is right, but the float comparison in loops is not safe.
The problem is that a binary floating point number cannot exactly represent 0.1
This would work.
for(i=0.0; i<=0.9001; i+=0.1){
printf("%6.1f ",i);