Floating Point Representation in C [duplicate] - c

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 4 years ago.
I'm not sure how floating point are represented in C, and how much of a precision someone could get.
In a c source file, I have the macro:
#define NUMBER 123.367
In the main function there are these 2 instructions:
float x = NUMBER;
printf("x is %f\n", x);
When I run it, I get:
x is 123.366997
Which is quite close to 123.367, but it kinda messes the purpose of the program.
Is there any way to round up x to the desired value? Or is this a flaw of floating point arithmetic-representation that can't be fixed?

You should use a double, not a float.
#include <stdio.h>
#define NUMBER 123.367
int main (void) {
float f = NUMBER;
double d = NUMBER;
printf("f is %f\n", f);
printf("d is %f\n", d);
return 0;
}
This will give you:
f is 123.366997
d is 123.367000
'double' uses 53 bits for precision, while a 'float' only uses 24.

Related

How does one make a floating point number stop rounding to an integer? [duplicate]

This question already has answers here:
Why does dividing two int not yield the right value when assigned to double?
(10 answers)
How to divide integers and get a float in C
(2 answers)
Closed 2 years ago.
I'm trying to write a basic programme, which gets a user's input, divides by seven, and then returns the result.
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int s = get_int("Input: ");
float f = (s / 7);
printf("%f\n", f);
}
Eg. if I input "8", I would expect 1.142857. But I instead simply get "1.000000". Why is this?
#include <stdio.h>
int main()
{
int s=4;
float f = ((float)s / 7);
printf("%f\n", f);
getch();
}
You just have to typecast the int to float. int/float division give you the floor of given integer whereas float/float division gives you float

Division of double and float in c [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 2 years ago.
i believe that double have x2 precision of float .
in my calculator 10/3 is 3.3333333333333333333333333333333
when i do the following code :
#include <stdlib.h>
#include <stdio.h>
void main() {
double var = (double )10 / (double )3;
float var2 = (float )10 / (float )3;
printf("%f %f \n" , var , var2 );
}
i get the same number of digits after 3, :
3.3333333333333335 3.3333332538604736
why do i get the same number of digits? and why the value is different ? and how to do a division for double and float and get all the numbers and digits in c (like in my calculator) ?
By default printf will only print a limited number of digits. On my system it's 6 digits. On your system it seems to be 16 digits.
To print more digits do:
printf("%.60f \n%.60f \n" , var , var2 );
Output:
3.333333333333333481363069950020872056484222412109375000000000
3.333333253860473632812500000000000000000000000000000000000000
As you can see neither float nor double can print
3.333333333333333333333333333333333333333333333333333333333333
but - obviously - double is closer than float.
BTW: It's not void main() {. It shall be int main(void) {

C Language scientific notation problems [duplicate]

This question already has answers here:
strange output in comparison of float with float literal
(8 answers)
Closed 7 years ago.
I have the following program:
float x = 3.e17;
printf("x = %f", x);
which gives the result:
x = 299999995292024832.000000
why is the result not 300000000000000000.000000?
#include <stdio.h>
#include <stdlib.h>
union
{
double d;
float f;
unsigned int ui[2];
} myun;
int main ( void )
{
float fx = 3.e17;
double dx = 3.e17;
printf("fx %f\n",fx);
printf("dx %lf\n",dx);
myun.f=fx;
printf("fx 0x%08X\n",myun.ui[0]);
myun.ui[0]++;
printf("fx %lf\n",myun.f);
myun.d=dx;
printf("dx 0x%08X 0x%08X\n",myun.ui[1],myun.ui[0]);
return(0);
}
(yes this is an incorrect/invalid way to use a union but it just happened to work)
fx 299999995292024832.000000
dx 300000000000000000.000000
fx 0x5C853A0D
fx 300000029651763200.000000
dx 0x4390A741 0xA4627800
wikipedia points out that single can handle up to 9 digits without a loss of precision and double 15-17. So right there is your answer, didnt necessarily need to do an experiment.
Because of limited float precision. Use double for more precision, but floating point is not always exact

Does float and double datatype work in gcc compilers? [duplicate]

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 .

Adding two doubles gives weird rounding result in C [duplicate]

This question already has answers here:
Why adding these two double does not give correct answer? [duplicate]
(2 answers)
Closed 8 years ago.
I'm a bit of C newbie but this problem is really confusing me.
I have a variable double = 436553940.0000000000 (it was cast from an Int) and an other variable double 0.095832496.
My result should be 436553940.0958324*96*, however I get 436553940.0958324*67*.
Why does this happen and how can I prevent it from happening?
The number you expect is simply not representable by a double. The value you receive is instead a close approximation based on rounding results:
In [9]: 436553940.095832496
Out[9]: 436553940.09583247
In [18]: 436553940.095832496+2e-8
Out[18]: 436553940.09583247
In [19]: 436553940.095832496+3e-8
Out[19]: 436553940.0958325
In [20]: 436553940.095832496-2e-8
Out[20]: 436553940.09583247
In [21]: 436553940.095832496-3e-8
Out[21]: 436553940.0958324
You've just run out of significand bits.
Doubles are not able to represent every number. We can write some C++ code (that implements doubles in the same way) to show this.
#include <cstdio>
#include <cmath>
int main() {
double x = 436553940;
double y = 0.095832496;
double sum = x + y;
printf("prev: %50.50lf\n", std::nextafter(sum, 0));
printf("sum: %50.50lf\n", sum);
printf("next: %50.50lf\n", std::nextafter(sum, 500000000));
}
This code computes the sum of the two numbers you are talking about, and stores it as sum. We then compute the next representable double before that number, and after that number.
Here's the output:
[11:43am][wlynch#watermelon /tmp] ./foo
prev: 436553940.09583240747451782226562500000000000000000000000000
sum: 436553940.09583246707916259765625000000000000000000000000000
next: 436553940.09583252668380737304687500000000000000000000000000
So, we are not able to have the calculation equal 436553940.0958324_96_, because that number is not a valid double. So the IEEE-754 standard (and your compiler) defines some rules that tell us how the number should be rounded, to reach the nearest representable double.

Resources