I would like to better understand floating point values and the imprecisions associated.
Following are two snippets with slight modifications
Snippet 1
#include <stdio.h>
int main(void)
{
float a = 12.59;
printf("%.100f\n", a);
}
Output:
12.5900001525878906250000000000000000000000000000000000000000000000000000000000000000000000000000000000
Snippet 2:
#include <stdio.h>
int main(void)
{
printf("%.100f\n", 12.59);
}
Output:
12.589999999999999857891452847979962825775146484375000000000000000000000000000000000000000000000000000
Why is there a difference in both the outputs? I'm unable to understand the catch.
In first case you have defined variable as a float and in second case you directly given the number.
System might be consider direct number as a double and not float.
So,I think may be it is because of system definition of float and double.
to get the consistent behaviour you can explicitly use floating point literal:
printf("%.100f\n", 12.59f);
In Snippet 1, your float gets cast into a double, and this casting causes a change in the value (due to the intricacies of floating point representation).
In Snippet 2, this cast doesn't happen, it's printed directly as a double.
To understand, try running the snippets below:
#include <stdio.h>
int main(void) {
double a = 12.59;
printf("%.100f\n", a);
return 0;
}
and
int main(void) {
float a = 12.59;
printf("%.100f\n", (double)a);
return 0;
}
Refer to this for more information: How does printf and co differentiate beetween float and double
Related
I'm solving a problem in Toph . In this problem I've to find out the empty space of a rectangle which has 2 equal circles in it.
here is the problem
#include <stdio.h>
float pi=3.1416;
int main()
{
int i,t;
float r,rest;
scanf("%d",&t);
for(i=1;i<=t;i++)
{
scanf("%f",&r);
rest=(4*r*2*r)-(2*pi*r*r);
printf("Case %d: %.2f\n",i,rest);
}
return 0;
Here is my solve. It returns a correct value for first test case but it fails to solve the second one.
What's the problem???
float pi=3.1416; is the cause of the problem. Under the math header file (#include <math.h>) there is a constant M_PI use it instead.
Edit:
Sorry, didn't read thoroughly, apparently the problem is in the floating point precision. If you change all float values into double it should work.
#include <stdio.h>
double pi=3.1416;
int main()
{
int i,t;
double r,rest;
scanf("%d",&t);
for(i=1;i<=t;i++)
{
scanf("%lf",&r);
rest=(4*r*2*r)-(2*pi*r*r);
printf("Case %d: %.2lf\n",i,rest);
}
return 0;
}
Unlike 2 and 8, the reason double is more accurate is because float cannot represent 3.1416 as well as the input values:
3.1416 -> 3.1415998935699462890625
40.082 -> 40.082000732421875
85.8 -> 85.8000030517578125
There's simply not enough precision, (note that IEEE-754 float, which is overwhelmingly used for float, stores it in base-2.) Most probably, the later numbers were probably specifically generated in order to fail the test cases. If one wants to know more, Don’t Store That in a Float, and What Every Computer Scientist Should Know About Floating-Point Arithmetic.
The numerical constant is 1.7168, which is exact assuming their version of pi, (times r*r.) The best one could with single-point precision is 1.7167999744415283203125, which is off by 2.55584716796875E-8. With a double, it's 1.71680000000000010373923942097, off by 1.0373923942097E-16, plus the values input.
This question already has answers here:
strange output in comparison of float with float literal
(8 answers)
Closed 4 years ago.
I am new to C language. Here is my question and code:
I have a constant and a variable with the same value and I try to compare them to check if they are equal. It seems to me that since they are assigned the same value, they should be equal but that is not the case.
#include <stdio.h>
#define mypi1 3.14
int main()
{
int ans;
float mypi2 = 3.14;
if(mypi1==mypi2)
{
ans=1;
}
else
{
ans=0;
}
printf("%i",ans);
return 0;
}
My output is 0. Which indicates they are not equal. What is the reasoning behind this? This is a really simple question but I could not find it anywhere. Please help and thanks in advance.
#define mypi1 3.14
float mypi2 = 3.14;
The first of those is a double type, the second is a double coerced into a float.
The expression mypi1==mypi2 will first convert the float back to a double before comparing (the idea is that, if one type is of lesser range/precision than the other, it's converted so that both types are identical).
Hence, if the if statement is failing, it's likely that you lose information in the double -> float -> double round-trip(a).
To be honest, unless you're using a great many floating point values (and storage space is a concern), you should probably just use double everywhere. If you do need float types, use that for both values:
#define mypi1 3.14f
float mypi2 = 3.14f;
Comparing two float variables will not involve any conversions.
(a) See, for example, the following complete program:
#include <stdio.h>
#define x 3.14
int main(void) {
float y = 3.14; // double -> float
double z = y; // -> double
printf("%.50f\n", x);
printf("%.50f\n", z);
}
In this, x is a double and z is a double that's gone through the round-trip conversion discussed above. The output shows the difference that can happen:
3.14000000000000012434497875801753252744674682617188
3.14000010490417480468750000000000000000000000000000
I am new to C programming. I keep getting this error, (in this case relating to code inside the cubic root function):
1>c:\users\r\documents\visual studio 2010\projects\lab5.c\lab5.c\lab5code.c(57): warning C4244: '=' : conversion from 'double' to 'float', possible loss of data
I have tried storing the cubic root calculation in a float, and then returning that to main, but still no luck. I have seen people compile my code with no problems.
I have so far tested the code on VS 2008, and 2010 express editions, same errors. I get this a lot, trying to figure out why.
//INCLUDE HEADER FILES
#include <stdio.h> //Defines printf, scanf & getch
#include <conio.h> //Defines get.ch
#include <stdlib.h> //Defines system("pause")
#include <math.h> //Defines math functions
// FUNCTION PROTOTYPES
void explain();
float get_value();
float cubic_root(float num);
void display(float x, float y);
int main(void)
{
float in,out;
//Variable Declarations
explain(); //Explain
in=get_value(); //Get Value from USER
out=cubic_root(in); //Calculations
display(in,out); //Output
}
//FUNCTION DEFINITIONS
void explain(void)
{
system("cls");
puts("This will take cubic root\nPress enter to continue...");
_getch();
}
float get_value(void)
{
float input;
fflush(stdin);
puts("Enter the number you want to cube root...\n");
scanf_s("%f",&input);
return(input);
}
float cubic_root(float num)
{
float div,total;
total=(pow(num,1.0/3.0));
return(total);
}
void display(float x, float y)
{
printf("%.1f, %.1f",x,y);
getch();
}
Because pow() returns a double, and you are assigning it to a float.
exp1=pow(num,0.33);
pow() returns a double and you're converting it to a float. That's why a warning is emitted and you should take notice of it.
The best thing to do is to refactor your code to use double precision variables. You will probably find that there is no performance hit in doing that as many low level floating point computations are at (or higher than) double precision anyway.
Note that pow(num, 0.33); is a grotesque approximation for a cube root. Use pow(num, 1.0 / 3); instead. You need to use 1.0 so the literal is evaluated (most likely at compile time) in floating point.
This:
exp1 = pow(num, 0.33);
assigns the return value of the pow() function, which has type double, to exp which has type float.
The fix is to use the powf() function instead:
float cubic_root(float num)
{
return powf(num, 1.f / 3.f);
}
You can of course just cast the result to float to tell the compiler you really mean this, but it seems extremely wasteful and pointless to do the exponentiation calculation using more precision than you really need, so don't do that.
I am willing to cast precise operations and for that purpose I need a way to
seperate a float number into an integer and a fractional part.
Is there any way for this?
There is a function included in math.h library called modf
With this function you can do just what are you trying to.
Example:
#include <stdio.h>
#include <math.h>
double ftof ()
{
double floating = 3.40, fractional, integer;
fractional = modf(floating, &integer);
printf ("Floating: %g\nInteger: %g\nFractional: %g", floating, integer, fractional); // when using printf, there are no floats
return fractional;
}
Output:
Floating: 3.40
Integer: 3
Fractional: 0.40
Note that using double in most of the cases is better than using float, despite that double
consumes twice the memory of float (4:8 bytes) hence the increased range and accuracy. Also in case you need more precise output from
bigger floating numbers when printing, you can try the printf() exponent format specifier %e instead of %g which only uses the
shortest representation of the floating decimal.
One other way using type cast.
#include <stdio.h>
#include <math.h>
void main()
{
float a = 3.4;
float a_frac = a - (int) a;
float a_int = a - a_frac;
printf("Number = %f, Integer = %f, Fraction = %f", a, a_frac, a_int);
}
A thought crossed my mind to separate them with some logic :
#include <iostream>
using namespace std;
int main()
{
double fr,i,in,num=12.7;
for(i=0;i<num;i++)
{
fr=num-i;
}
cout<<"num: "<<num;
cout<<"\nfraction: "<<fr;
in=num-fr;
cout<<"\nInteger: "<<in;
}
Hope this was what you were searching for:) .
#include <bits/stdc++.h>
using namespace std;
int main()
{
double n;
cin>>n;
double fr = n-((int)n);
cout<<"int "<<(int) n<<"\n";
cout<<"fraction "<< fr;
return 0;
}
#include <stdio.h>
int main(){
float var = 0.612;
printf("%f\n",var);
printf("%f\n",var*100);
return 0;
}
o/p
0.612000
61.199997
I found that for JavaScript, we have .tofixed() method.
How do we get a fix for this in C?
You can specify the precision when printing:
printf("%.3f\n", 100 * var);
Since the exact number you're having probably isn't representable in the float itself, there is no operation you can do on the number itself to "remove" the decimals, it's all a matter of how you choose to present the data.