C Programming Basics [duplicate] - c

This question already has answers here:
problems in floating point comparison [duplicate]
(2 answers)
Explain this floating point behavior
(6 answers)
Closed 9 years ago.
Why does the code given below Prints b on the Screen?
#include<stdio.h>
main()
{
float a = 5.6;
if(a == 5.6)
{
printf("a");
}
else
{
printf("b");
}
}

As floating point Numbers can't be matched exactly (because between each 2 numbers you choose are infinite other numbers). A machine can't represent them all and is forced to represent them with a moddel of only some floating point numbers it is able to represent.
So in your case, the system is probably not storing 5.6 because that's a number your machine doesn't want to represent. Instead it is storing something which is pretty close to 5.6 into the memory.
So if you do comparing with floating point numbers you never should check for equivalenz. Instead you should use the system C define FLT_EPSILON and check for
if (((a - 5.6) > -FLT_EPSILON) && ((a - 5.6) < FLT_EPSILON))
{
...
}
Where FLT_EPSILON is the smallest representable float type value.
So if the difference from a to 5.6 is absolute smaller as EPSILON, you can be sure it WAS equal, but the machine has chosen the next number it knows instead of 5.6.
The same would be DBL_EPSILON for double type.
this types are defined in float.h

When you want a float value don't forget to add f
#include<stdio.h>
main()
{
float a = 5.6f;
if(a == 5.6f)
{
printf("a");
}
else
{
printf("b");
}
}
prints a as expected.
The problem was that both 5.6 are defined as double literals, and the a got converted into a float while in the if it's still comparing it to a double value so you get false.
Actually adding f only inside the if would be enough, but better safe then sorry.

floating point number in c is double by default. If you want use as float you need to add f at end of the number. try below code it gives a
#include<stdio.h>
main()
{
float a = 5.6;
if(a == 5.6f)
{
printf("a");
}
else
{
printf("b");
}

Related

"==" operator seeems not to work for floating point numbers [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed last year.
Can someone please explain the output here?
#include <stdio.h>
int main(void) {
float f = 0.1 ;
printf ("%f\n",f ) ;
if (f == 0.100000) {
printf ("true ") ;
}
else {
printf ("False") ;
}
return 0;
}
output:
0.100000
False
You are trying to compare a float number with a double. The number 0.100000is considered as doubletype unless you specify with a trailing f that it is a float. Thus:
int main(){
float x = 0.100000;
if (x == 0.100000)
printf("NO");
else if (x == 0.100000f)
// THE CODE GOES HERE
printf("YES");
else
printf("NO");
}
You mat refer to single precision and double precision for theoritical details
Objects of the types float and double are stored with different precisions.
You should write
if (f == 0.100000f) {
trying to compare two floats.
Also it would be better to initialize the variable f with a constant of the type float
float f = 0.1f;
0.100000 is double by default, try 0.100000f. if you need to compare with double, you need to try something described here.

How to compare double variables in the if statement

As I am trying to compare these doubles, it won't seem to be working correctly
Here it goes: (This is exactly my problem)
#include <stdio.h>
#include <math.h>
int main () {
int i_wagen;
double dd[20];
dd[0]=0.;
dd[1]=0.;
double abstand= 15.;
double K_spiel=0.015;
double s_rel_0= K_spiel;
int i;
for(i=1; i<=9; i++)
{
i_wagen=2*(i-1)+2;
dd[i_wagen]=dd[i_wagen-1]-abstand;
i_wagen=2*(i-1)+3;
dd[i_wagen]=dd[i_wagen-1]-s_rel_0;
}
double s_rel=dd[3-1]-dd[3];
if((fabs(s_rel) - K_spiel) == 0.)
{
printf("yes\n");
}
return(0);
}
After executing the programm, it wont print the yes.
How to compare double variables in the if statement?
Take under account limited precision of the double representation of floating point numbers!
Your problem is simple and covered in Is floating point math broken?
Floating point operations are not precise. The representation of the given number may not be precise.
For 0.1 in the standard binary64 format, the representation can be written exactly as 0.1000000000000000055511151231257827021181583404541015625
Double precision (double) gives you only 52 bits of significant, 11 bits of exponent, and 1 sign bit. Floating point numbers in C use IEEE 754 encoding.
See the output of your program and the possible fix where you settle down for the variable being close to 0.0:
#include <stdio.h>
#include <math.h>
#define PRECISION 1e-6
int main (void) {
int i_wagen;
double dd[20];
dd[0]=0.;
dd[1]=0.;
double abstand= 15.;
double K_spiel=0.015;
double s_rel_0= K_spiel;
int i;
for(i=1; i<=9; i++)
{
i_wagen = 2*(i-1)+2;
dd[i_wagen] = dd[i_wagen-1]-abstand;
i_wagen = 2*(i-1)+3;
dd[i_wagen] = dd[i_wagen-1] - s_rel_0;
}
double s_rel = dd[3-1]-dd[3];
printf(" s_rel %.16f K_spiel %.16f diff %.16f \n" , s_rel, K_spiel, ((fabs(s_rel) - K_spiel)) );
if((fabs(s_rel) - K_spiel) == 0.0) // THIS WILL NOT WORK!
{
printf("yes\n");
}
// Settle down for being close enough to 0.0
if( fabs( (fabs(s_rel) - K_spiel)) < PRECISION)
{
printf("yes!!!\n");
}
return(0);
}
Output:
s_rel 0.0150000000000006 K_spiel 0.0150000000000000 diff 0.0000000000000006
yes!!!
You're comparing x to two different matrix entries: the first if compares x to coeff[0][0], the second to coeff[0][1]. So if x is greater than coeff[0][0] and less than or equal to coeff[0][1] the program will execture the final else branch. You probably want to compare x to the same matrix entry in both if statements. And in that case, the last else branch would be useless, since one of the three cases (less than, equal to or greater than) MUST be true.
First, dd[i_wagen-1] as used in the statement:
dd[i_wagen]=dd[i_wagen-1]-abstand;
is uninitialized. Code will run, but will have unpredictable results.
To initialize, you can use:
double dd[20]={0}; //sufficient
or possibly
double dd[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //explicit, but not necessary
Moving to your actual question, it all comes down to this statement:
if((fabs(s_rel) - K_spiel) == 0.)
You have initialized K_spiel to 0.015. And at this point in your execution flow s_rel appears to be close to 0.015. But it is actually closer to 0.0150000000000006. So the comparison fails.
One trick that is commonly used is to define an epsilon value, and use it to determine if the difference between two floating point values is small enough to satisfy your purpose:
From The Art of Computer Programming, the following snippet uses this approach, and will work for your very specific example: (caution: Read why this approach will not work for all floating point related comparisons.)
bool approximatelyEqual(float a, float b, float epsilon)
{
return fabs(a - b) <= ( (fabs(a) < fabs(b) ? fabs(b) : fabs(a)) * epsilon);
}
So replace the line:
if((fabs(s_rel) - K_spiel) == 0.)
with
if(approximatelyEqual(s_rel, K_spiel, 1e-8)

why if(a==2.3) evaluates false when float a=2.3 [duplicate]

This question already has answers here:
Why are floating point numbers inaccurate?
(5 answers)
Closed 6 years ago.
#include<stdio.h>
void main()
{
float a = 2.3;
if(a == 2.3) {
pritnf("hello");
}
else {
printf("hi");
}
}
It prints "hi" in output, or we can say that if condition is getting false value.
#include<stdio.h>
void main()
{
float a = 2.5;
if(a == 2.5)
printf("Hello");
else
printf("Hi");
}
It prints hello.
The variable a is a float that holds some value close to the mathematical value 2.3.
The literal 2.3 is a double that also holds some value close to the mathematical value 2.3, but because double has greater precision than float, this may be a different value from the value of a. Both float and double can only represent a finite number of values, so there are necessarily mathematical real numbers that cannot be represented exactly by either of those two types.
In the comparison a == 2.3, the left operand is promoted from float to double. This promotion is exact and preserves the value (as all promotions do), but as discussed above, that value may be a different one from that of the 2.3 literal.
To make a comparison between floats, you can use an appropriate float literal:
assert(a == 2.3f);
// ^
2.3 with binary representation is 01000000000100110011001100110011...
so you are not able to set a float exactly to 2.3
with double precision you get something similar: 2.299999952316284
you converted a double to float when you wrote:
float a = 2.3;
the if checks if the float a is equal to double 2.299999952316284
you should write:
float a = 2.3f;
and you can check:
if (a == 2.3f) {
...
}
i would rather test with:
if (fabs(a - 2.3f) < 0.00001) {
...
}
the 2.5 represented with bits is: 01000000001000000000000000000000
EDIT: fabs is part of the <math.h> or <cmath>
Read this: article
Comparing floating point values is not as easy as it might seem, have a look at Most effective way for float and double comparison.
It all boils down to the fact, that floating point numbers are not exact (well
most are not). Usually you compare 2 floats by allowing a small error window (epsilon):
if( fabs(a - 2.3f) < epsion) { ... }
where epsilon is small enough for your calculation, but not too small (bigger than Machine epsilon).

How do I determine whether the value of a float is a whole number? [duplicate]

This question already has answers here:
Checking if float is an integer
(8 answers)
Closed 8 years ago.
I have a program in which i need to print FLOAT in case of a float number or print INTEGER in case of a regular number.
for Example pseudo code
float num = 1.5;
if (num mod sizeof(int)==0)
printf ("INTEGER");
else
printf("FLOAT");
For example:
1.6 would print "FLOAT"
1.0 would print "INTEGER"
Will something like this work?
All float types have the same size, so your method won't work. You can check if a float is an integer by using ceilf
float num = 1.5;
if (ceilf(num) == num)
printf ("INTEGER");
else
printf("FLOAT");
You can use modff():
const char * foo (float num) {
float x;
modff(num, &x);
return (num == x) ? "INTEGER" : "FLOAT";
}
modff() will take a float argument, and break it into its integer and fractional parts. It stores the integer part in the second argument, and the fractional part is returned.
The "easy" way, but with a catch:
You could use roundf, like this:
float z = 1.0f;
if (roundf(z) == z) {
printf("integer\n");
} else {
printf("fraction\n");
}
The problem with this and other similar techniques (such as ceilf) is that, while they work great for whole number constants, they will fail if the number is a result of a calculation that was subject to floating-point round-off error. For example:
float z = powf(powf(3.0f, 0.05f), 20.0f);
if (roundf(z) == z) {
printf("integer\n");
} else {
printf("fraction\n");
}
Prints "fraction", even though (31/20)20 should equal 3, because the actual calculation result ended up being 2.9999992847442626953125.
So how do we deal with this?
Any similar method, be it fmodf or whatever, is subject to this. In applications that perform complex or rounding-prone calculations, usually what you want to do is define some "tolerance" value for what constitutes a "whole number" (this goes for floating-point equality comparisons in general). We often call this tolerance epsilon. For example, lets say that we'll forgive the computer for up to +/- 0.00001 rounding error. Then, if we are testing z, we can choose an epsilon of 0.00001 and do:
if (fabsf(roundf(z) - z) <= 0.00001f) {
printf("integer\n");
} else {
printf("fraction\n");
}
You don't really want to use ceilf here because e.g. ceilf(1.0000001) is 2 not 1, and ceilf(-1.99999999) is -1 not -2.
Choose a tolerance value that is appropriate for your application. For more information, check out this article on comparing floating-point numbers.
Will something like this work?
No. For example on the x86_32 and ARM 32 bit architectures sizeof(int) == 4 and sizeof(float) == 4.
Also whatever you think mod is, it clearly shows you don't understand what the sizeof operator does.

Labwindows strange behavior when adding DOUBLE numbers [duplicate]

This question already has answers here:
Floating point comparison revisited
(4 answers)
Closed 8 years ago.
I am running the following block of code inside a CALLBACK function for a timer.
if (start_value <= end_value)
{
start_value += increment_value;
}
else
{
return 0;
}
all three variables are defined as DOUBLE.
Double start_value = 26.0;
Double end_value = 28.0;
increment_value = 0.1;
when adding the increment_value to start_value, the value of the variable start_value does not simply reflect the expected result of the addition. For example, when start_value is 26.0, after one addition, the value of start_value is 26.10000000001. The trailing 1 causes problems later on in the code, because when the expected result of the comparison is expected to be TRUE, it is evaluated as false because of the trailing 1.
Why is this happening?
Eshan, The == operator is looking for an exact match, and should be used exclusively for integer comparisons (where exact is possible). So, "why is this happening?" because 26.10000000001 is not equal to 26.1. The difference between the two is sometimes referred to as floating point error.
As long as we are using binary storage of floating point, there will continue to be floating point error. This requires that methods to compare floating points have to be different than when comparing integers. (i.e. for floats, cannot use (x == y) ?. A quick and dirty alternative to "==" when comparing floats is to do something like this: if(abs(x-y)<epsilon ){//equal} where epsilon is some small tolerance value like 0.000001
So, try something like this instead:
int main(void)
{
double start_value = 26.0;
double end_value = 28.0;
double increment_value = 0.1;
#define EPSILON 0.000001
while(fabs(start_value-end_value)>EPSILON )
{
printf("not equal\n");
start_value += increment_value;
}
printf("equal\n");
getchar();
}
Note: choose epsilon value to match the neighborhood of significant digits in the comparisons you will do.
There are many other good methods, (and many who will say this is not one of them) but I have used this one for years, and for my purposes, it has worked well.
HERE is a link talking a little about this, and other methods.

Resources