Adding floating point to the integer - c

i need help with my homework, i need to make a c program that gets a double
and prints the number without the floating point for example
gets 157.89943912 and prints 15789943912
so i made this
void main()
{
double x = 157.89943912;
while (x - (int)x > 0.0000001)
{
x *= 10;
}
printf("%lf", x);
scanf_s("%d");
}
now because of double zero inaccuracy the loop runs forever
but if i put 157.8994391 (one less floating point decimal)
it works..
thanks in advance!.

Related

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)

From a float to an integer

Given this code that my professor gave us in an exam which means we cannot modify the code nor use function from other libraries (except stdio.h):
float x;
(suppose x NOT having an integer part)
while (CONDITION){
x = x*10
}
I have to find the condition that makes sure that x has no valid number to the right of decimal point not giving attention to the problems of precision of a float number (After the decimal point we have to have only zeros). I tried this condition:
while ((fmod((x*10),10))){
X = X*10
}
printf(" %f ",x);
example:
INPUT x=0.456; --------> OUTPUT: 456.000
INPUT X=0.4567;--------> OUTPUT; 4567.000
It is important to be sure that after the decimal point we don't have any
significant number
But I had to include math.h library BUT my professor doesn't allow us to use it in this specific case (I'm not even allowed to use (long) since we never seen it in class).
So what is the condition that solve the problem properly without this library?
As pointed out here previously:Due to the accuracy of floats this is not really possible but I think your Prof wants to get something like
while (x - (int)x != 0 )
or
while (x - (int)x >= 0.00000001 )
You can get rid of the zeroes by using the g modifier instead of f:
printf(" %g \n",x);
There is fuzziness ("not giving attention to the problems of precision of a float number") in the question, yet I think a sought answer is below, assign x to an integer type until x no longer has a fractional part.
Success of this method depends on INT_MIN <= x <= INT_MAX. This is expected when the number of bits in the significant of float does not exceed the value bits of int. Although this is common, it is not specified by C. As an alternative, code could with a wider integer type like long long with a far less chance of the range restriction issue.
Given the rounding introduced with *10, this method is not a good foundation of float to text conversion.
float Dipok(float x) {
int i;
while ((i=x) != x) {
x = x*10;
}
return x;
}
#include <assert.h>
#include <stdio.h>
#include <float.h>
void Dipok_test(float x) {
// suppose x NOT having an integer part
assert(x > -1.0 && x < 1.0);
float y = Dipok(x);
printf("x:%.*f y:%.f\n", FLT_DECIMAL_DIG, x, y);
}
int main(void) {
Dipok_test(0.456);
Dipok_test(0.4567);
return 0;
}
Output
x:0.456000000 y:456
x:0.456699997 y:4567
As already pointed out by 2501, this is just not possible.
Floats are not accurate. Depending on your platform, the float value for 0.001 is represented as something like 0.0010000001 in fact.
What would you expect the code to calculate: 10000001 or 1?
Any solution will work for some values only.
I try to answer to my exam question please if I say something wrong correct me!
It is not possible to find a proper condition that makes sure that there are no valid number after the decimal point. For example : We want to know the result of 0.4*20 which is 8.000 BUT due to imprecision problems the output will be different:
f=0.4;
for(i=1;i<20;i++)
f=f+0.4;
printf("The number f=0.4*20 is ");
if(f!=8.0) {printf(" not ");}
printf(" %f ",8.0);
printf("The real answer is f=0.4*20= %f",f);
Our OUTPUT will be:
The number f=0.4*20 is not 8.000000
The real answer is f=0.4*20= 8.000001

0.1 increment in a While Loop (C Programming)

I am in an introductory C programming class. Our latest project has us writing code to tabulate x and sqrt(x) values from 1-10 with a 0.1 step using a while loop. When I try to do the 0.1 increment, however, nothing is added to the starting integer 1 and the program runs in an infinite loop. I'll post the code below. Other than it not doing the step, the program runs fine (and works with other increments like 1, etc.). How do I resolve this?
#include <stdio.h>
#include <math.h>
int main(void)
{
int x=1;
double sq_rt;
printf("Square Root Table: \n");
printf("Value of X Square Root of X\n");
while (x <= 10)
{
sq_rt = sqrt (x);
printf("%6i %20f \n", x, sq_rt);
x += 1e-1;
}
return 0;
}
An int type will only allow you to store whole numbers (i.e. -2, -1, 0, 1, 2 etc). To store numbers with a decimal point, you'll need a double precision (or double) type. Change the first line of main() to:
double x = 1.0;
If you try to add 1e-1 to an int, it will convert it to an int first - the type of x - which when truncated will end up being zero, so you'll never actually add anything to x.
The line in your program which reads
x += 1e-1;
is performing operations equivalent to
x = (int)(((double)x) + 0.1);
In other words, x is first converted to a double, then 0.1 is added to it, resulting in 1.1. This value is then converted to int, resulting in a value of 1, which is assigned to x.
The fix is to change the type of x to a floating point type such as float or double.
Share and enjoy.
the following code is a suggestion on how to perform the desired algorithm.
#include <stdio.h>
#include <math.h>
// define the magic numbers, don't embed them in the code
#define UPPER_LIMIT (10.0)
#define STEP_SIZE (0.1)
int main(void)
{
double x=1.0;
double sq_rt;
printf("Square Root Table: \n");
printf("Value of X Square Root of X\n");
// due to ambiguities in 'real' values,
// this loop will iterate approx. 90 times.
while( x < UPPER_LIMIT )
{
sq_rt = sqrt (x);
// display the two double values
// note: long float conversion values
// because the underlying numbers are double
// note: blanks for alignment with column headers
printf("%9.6lf %16.13lf \n", x, sq_rt);
// increase base value by increment of 0.1
x += STEP_SIZE;
} // end while
return 0;
} // end function: main

C Help! Floating Points

I have this question:
We claim that it is unsafe to use equality testing with floating point numbers because the arithmetic operations introduce rounding errors which mean that two numbers which ought to be equal are not.
For this program, you should pick a number N, and write a program to show for which of the integers x between 1 and 1000 the equality
(x+1)/N = (x/N) + (1/N) fails
#include <stdio.h>
int main () {
int x;
float N = 50;
for (x=0; x<1001; x++) {
if ((x+1)/N != (x/N) + (1/N))
{
printf("%i\n",x);
}
}
}
Is this correct?
Thanks.
Your program is wrong. It should start with x=1 instead of x=0.
But beside that, you should pick two examples (one that has been printed by the program and one that hasn’t) and calculate them by hand. With just pen and paper and the IEEE 754-1985 rules. Then print both sides of the equation and compare them to your hand-computed results.

C and casting - why does this program stop at 6?

I edited a C program for my assignment, previously there wasn't typecasting and the iteration stopped at i=1, now with the typecasting it stops at i=6.
Any ideas why? Thanks in advance!
int main(void)
{
int i = 0;
double d = 0.0;
while ( (i == (int) (d * 10)) && (i < 10) )
{
i = i + 1;
d = (double) (d + 0.1);
printf("%d %lf\n", i, d);
}
printf("%d %lf\n", i, d);
getch();
return 0;
}
Floating point arithmetic is inexact. The value 0.1 is not exactly representable in binary floating point. The recommended reading here is: What Every Computer Scientist Should Know About Floating-Point Arithmetic.
At some point in the program, d becomes slightly less than i/10 due to rounding error, and so your loop terminates.
In addition to the other answers, I'd like to answer the question why the loop terminates earlier with the condition i == (d * 10) than with i == (int) (d * 10).
In the first case, int value at the left side of == is promoted to double, so the inequality happens when the accumulated error in d*10 is either positive or negative (e.g. 0.999999 or 1.000001).
In the 2nd case, the right side is truncated to int, so the inequality happens only when the error is negative (e.g. 5.999999). Therefore, the 1st version would fail earlier.
As has been stated many times before, the reason this doesn't work is that binary floating point numbers cannot represent all decimal floating point binary numbers, it just isn't possible. To read more, check out this really great article:
What Every Programmer Should Know About Floating-Point Arithmetic
Now, on the more practical side of things, when using floating point and comparing it to another number, you should almost always round the value or use an epsilon value, like this:
if (ABS(doubleValue - intValue) < 0.00001) // 0.00001 is a margin-of-error for floating point arithmetic
// the two numbers are even (or close to it)

Resources