This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 10 months ago.
I have this code and I want to print all the numbers of an arithmetic progression of ratio 0.3 but when I use the following code it includes 3, when I wanted all non-negative below 3. What would be another way to do it?
#include <stdio.h>
int main() {
double x = 0;
while(x < 3.0) {
printf("x = %f\n", x);
x += 0.3;
}
return 0;
}
3/10 is a periodic number in binary just like 1/3 is a periodic number in decimal. As such, it can't be accurately represented by a floating point number.
$ perl -e'printf "%.100g\n", 0.3'
0.299999999999999988897769753748434595763683319091796875
(Used Perl here because it was terser. The choice of language isn't important because it's a property of floating point numbers, not the language.)
In your case, the problem can be avoided by scaling the numbers up by a factor of ten.
#include <stdio.h>
int main() {
int x = 0;
while(x < 30) {
printf("x = %f\n", x/10.0);
x += 3;
}
return 0;
}
Related
This question already has answers here:
Is floating point math broken?
(31 answers)
Why are floating point numbers inaccurate?
(5 answers)
Is floating-point == ever OK?
(14 answers)
Closed 11 months ago.
sample code is here, desire output is 2 ::
#include <stdio.h>
int main()
{
double i, a, b;
int j;
for (i = 0; i <= 3; i = i + .20)
{
if (i == 2)
{
printf("I=%lf\n", i);
}
}
}
When I use
#include <stdio.h>
int main()
{
double i, a, b;
int j;
for (i = 0; i <= 3; i = i + .25)
{
if (i == 2)
{
printf("I=%lf\n", i);
}
}
}
it works; but in the first case, it is not working. WHY ??
The short answer is that the use of a floating control variable for a for loop is unwise... comparing a floating value for equality is even less so.
Due to the storage of floating point numbers as a mantissa and an exponent, your 0.20000000 may well be 0.199999999...9 or 020000000...01 thus the comparison fails.
Typically, 0.25 and 2.000 will store exactly, as they are powers of 2. Hence a step of 0.25 works as anticipated.
MISRA C:2012 has Rule 14.1 to protect against using float or doubles as loop counters... and previously had a Rule to protect against testing float/double for equality -perhaps we should reinstate that Rule.
This question already has answers here:
C program to convert Fahrenheit to Celsius always prints zero
(6 answers)
Closed 2 years ago.
int number = round(2/3);
printf("%i", number);
the output is
0
I expected to get 1 as 0.6 recurring should round up - i know for sure that the problem is with recurring decimals as they are always rounded down - I'm not sure how to round up in this kind of scenario.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int main(void) {
double number = round(2.0/3.0);
printf("%0.f", number);
}
Output = 1
You can use double or float for rounding numbers
Without floating point calculations, the following will round to nearest using just integer division:
int a = 2;
int number = (a + 1) / 3; // = 1
In general, rounding a / b to the nearest integer is equivalent to truncating (a + b / 2) / b.
use double or float number. in definition and in printf
#include <stdio.h>
int main(void)
{
double number = (double)2/3;
printf("%.f", number);
}
This question already has answers here:
How best to sum up lots of floating point numbers?
(5 answers)
Is floating point math broken?
(31 answers)
Closed 4 years ago.
Here I have a function sum() of type float that takes in a pointer t of type float and an integer size. It returns the sum of all the elements in the array. Then I create two arrays using that function. One that has the BIG value at the first index and one that has it at the last index. When I return the sums of each of those arrays I get different results. This is my code:
#include <stdlib.h>
#include <stdio.h>
#define N 1024
#define SMALL 1.0
#define BIG 100000000.0
float sum(float* t, int size) { // here I define the function sum()
float s = 0.0;
for (int i = 0; i < size; i++) {
s += t[i];
}
return s;
}
int main() {
float tab[N];
for (int i = 0; i < N; i++) {
tab[i] = SMALL;
}
tab[0] = BIG;
float sum1 = sum(tab, N); // initialize sum1 with the big value at index 0
printf("sum1 = %f\n", sum1);
tab[0] = SMALL;
tab[N-1] = BIG;
float sum2 = sum(tab, N); // initialize sum2 with the big value at last index
printf("sum2 = %f\n", sum2);
return 0;
}
After compiling the code and running it I get the following output:
Sum = 100000000.000000
Sum = 100001024.000000
Why do I get different results even though the arrays have the same elements ( but at different indexes ).
What you're experiencing is floating point imprecision. Here's a simple demonstration.
int main() {
float big = 100000000.0;
float small = 1.0;
printf("%f\n", big + small);
printf("%f\n", big + (19 *small));
return 0;
}
You'd expect 100000001.0 and 100000019.0.
$ ./test
100000000.000000
100000016.000000
Why'd that happen? Because computers don't store numbers like we do, floating point numbers doubly so. A float has a size of just 32 bits, but can store numbers up to about 3^38 rather than the just 2^31 a 32 bit integer can. And it can store decimal places. How? They cheat. What it really stores is the sign, an exponent, and a mantissa.
sign * 2^exponent * mantissa
The mantissa is what determines accuracy and there's only 24 bits in a float. So large numbers lose precision.
You can read about exactly how and play around with the representation.
To solve this either use a double which has greater precision, or use an accurate, but slower, arbitrary precision library such as GMP.
Why do I get different results even though the arrays have the same elements
In floating-point math, 100000000.0 + 1.0 equals 100000000.0 and not 100000001.0, but 100000000.0 + 1024.0 does equal 100001024.0. Given the value 100000000.0, the value 1.0 is too small to show up in the available bits used to represent 100000000.0.
So when you put 100000000.0 first, all the later + 1.0 operations have no effect.
When you put 100000000.0 last, though, all the previous 1000+ 1.0 + 1.0 + ... do add up to 1024.0, and 1024.0 is "big enough" to make a difference given the available precision of floating point math.
This question already has answers here:
C program to convert Fahrenheit to Celsius always prints zero
(6 answers)
Closed 7 years ago.
I've written a code for the following program but the output seems to be wrong.
Question:
https://www.hackerrank.com/challenges/plus-minus
Code:
#include <stdio.h>
int main() {
int N,num,i,cp=0,cn=0,cz=0;
double fp,fn,fz;
scanf("%d",&N);
for(i=0;i<N;i++)
{
scanf("%d",&num);
if(num>0)
cp=cp+1;
else if(num==0)
cz=cz+1;
else
cn=cn+1;
}
fp=cp/N;
fn=cn/N;
fz=cz/N;
printf("%lf\n%lf\n%lf",fp,fn,fz);
return 0;
}
The Output comes as:
0.000000
0.000000
0.000000
Istructions:
fp=cp/N;
fn=cn/N;
fz=cz/N;
Are performed as integer division.
Change your code to:
fp=(double)(cp)/(double)(N);
fn=(double)(cn)/(double)(N);
fz=(double)(cz)/(double)(N);
you are doing an integer division which creates only integer results. If you want to calculate floating point results you need to perform floating point divisions.
int a = 1;
int b = 3;
int c = a / b;
// c is now 0 -> integer division
double i = 1.0;
double j = 3.0;
double k = i / j;
// k is now 0.3333333 -> floating point division
For correct result cast these expression's to double-
like this
fp=cp/N; // fp=(double)cp/N;
fn=cn/N; // fn=(double)cn/N;
fz=cz/N; // fz=(double)cz/N;
Working code
In previous case if cp(or cn or cz) is less than N then due to integer division you will get 0(fraction part will be discarded). Therefore m these casts .
Another method would be to use all variables as double .
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);