Time = distance over speed in C - c

I'm trying to find the time taken to travel over an inputted distance going at a constant speed in C. The code I have functions but the output is printed as 0? Any idea what is going wrong?
#include <stdio.h>
#include <stdlib.h>
int main() {
int distance, speed = 80;
float time;
// This is how to read an int value
printf("Please enter a distance in kilometers to be covered at 80KPH. \n");
scanf("%d", & distance);
printf("You typed: %d\n", distance);
printf("\n");
time = distance / speed;
printf("It will take you %.2f to cover ", time);
}

Because the two operands are integers, the compiler generates code for integer division. But you want real division. So cast one or more of the operands to a floating point type and the compiler will emit code for real division.
time = (float) distance / time;
Integer division is what you learnt in elementary school. So, 11/3 is 3 remainder 2, for example. In C the expression 11/3 evaluates to 3. This is integer division. In your case it seems that the numerator (distance) is less than the denominator (time) and so the expression
distance / time
evaluates to 0.
This is a common confusion caused by the overloading of the division operator. This operator means integer division if both operands are integers, otherwise it is real division.
The key point to learn is that it is the types of the operands that determine whether integer or real division is used. The type of the variable in which the result is stored has no influence on this choice.

Change
time = distance / speed;
to
time = (float) distance / speed;
You were doing an integer division instead of a floating point division.

Once you changed the code according to what the others said (cast to float or double first), you will also need to change the format specifier from "%d" to "%f" for displaying floating point numbers (be it float or double), or else you will see garbage in your output.
EDIT: Sorry for mixing this up. I was thinking of a fix where you define speed and distance as float instead of int. In that case, you can simply convert "int" to "float" and "%d" to "%f" (possibly with accuracy and/or rounding flags). However, this will change the way the program works (because the user can now enter non-integral values), so it might not be what you want.

Related

C - int arithmetic calculation with float (beginner)

I have user integer input input and wanted to output the calculation with the input by division. The return had been 0 rather than decimals results. Wanted to prevent use of initialize the variable input with int rather than float to prevent possible errors in later data input with delimiter .
Is there any way to calculate float result w/ int input other than assigning float for the variable input ?
Source:
#include <stdio.h>
#include <stdlib.h>
int main() {
int input;
printf("Enter data:");
scanf("%d", &input);
printf("Output: %f", (input / 7));
return 0;
}
Return:
Input: 6
0.0000
Everything in C has a type, including constants like 7 which is type int, 7.0f which is type float or 7.0 which is type double.
Whenever mixing fixed point and floating point operands in the same operation with two operands (generally a bad idea), then the fixed point operand is converted to floating point. This is called "the usual arithmetic conversions".
Examples:
int input;, input / 7. Both operands are int, no promotion occurs, the result will be of type int. This has everything to do with the / operator and nothing to do with where you place the result. The divison will get carried out on int type, so if you wanted it to be type float, it's already too late. Something like float f = input / 7 will not affect the type used by the division in any way. It will only convert the resulting int to float.
int input;, input / 7.0f. One operand is type int, the other is type float. The usual arithmetic conversions state that the int operand will get converted to float before the division. So this would solve the problem.
However, here is a better idea: Simply never mix fixed point and floating point in the same expression, because the potential for bugs is huge. Instead do this:
scanf("%d", &input);
float f_input = (float)input;
printf("Output: %f", (f_input / 7.0f);
Now nothing goes on implicitly, all implicit conversions have been removed. The cast is not necessary, but creates self-documenting code saying: "yes I do mean to make this a float type rather than had it happen by chance/accident".
(Advanced topic detail: printf actually converts the passed float to double, but we need not worry about that.)
You need input/7 to be performed with floating point math, rather than integer math.
Like this...
printf("Output: %f", (input / 7.0));
This link explains a bit better how C/C++ deals with mixing floats/doubles/ints etc.
Does one double promote every int in the equation to double?

Is there any way to not lose the precision and still get the value?

First off, I'm a total beginner at C, with prior experience of programming in Java and Python. The goal of the program was to add 2 numbers. While I was playing with the code, I encountered an issue with precision. The issue was caused when I added 2 numbers- 1 of float data type and the other of double data type.
Code:
#include <stdio.h>
int main() {
double b=20.12345678;
float c=30.1234f;
printf("The Sum of %.8f and %.4f is= %.8f\n", b, c, b+c);
return 0;
}
Output:
The Sum of 20.12345678 and 30.1234 is= 50.24685651
However, the correct output should be: 50.24685678
float values are accurate up-to 6 decimal places, and so is the output.
I tried casting the values explicitly to double type, but its still of no use.
PS: When I convert the variable type from float to double, the output is precise; but is there any other way to add float and double integers without messing with their data type?
Thank You.
float only guarantees 6 decimal digits of precision, so any computation with a float (even if the other operands are double, even if you're storing the result to a double) will only be precise to 6 digits.
If you need greater precision, then limit yourself to double or long double. If you need more than 10 decimal digits of precision, then you'll need to use something other than the native floating point types and library functions. You'll either need to roll your own, or use an arbitrary precision math library like GNU MP.
The value assigned to c can't be expressed exactly so it gets assigned the next closest value. You don't see that when printing to 4 decimal places but you do see it if you print 8:
printf("The Sum of %.8f and %.8f is= %.8f\n", b, c, b+c);
Output:
The Sum of 20.12345678 and 30.12339973 is= 50.24685651
So the constant 30.1234f is already imprecise enough for the calculation you're trying to do.

How to round a float by casting as an int in C

So I am a second semester freshman in college. My teacher wants us to write a function that round a floating point number to the nearest hundredth. He said that we need to convert the floating point into an integer data type and then covert it back to a floating point. That's all he said. I have spent at least 5 hours trying different ways to do this.
This is my code so far:
#include <stdio.h>
int rounding(int roundedNum);
int main()
{
float userNum,
rounded;
printf("\nThis program will round a number to the nearest hundredths\n");
printf("\nPlease enter the number you want rounded\n>");
scanf("%f", &userNum);
rounded = rounding (userNum);
printf("%f rounded is %f\n", userNum, rounded);
return 0;
}
int rounding(int roundedNum)
{
return roundedNum;
}
Your instructor may be thinking:
float RoundHundredth(float x)
{
// Scale the hundredths place to the integer place.
float y = x * 100;
// Add .5 to cause rounding when converting to an integer.
y += .5f;
// Convert to an integer, which truncates.
int n = y;
// Convert back to float, undo scaling, and return.
return n / 100.f;
}
This is a flawed solution because:
Most C implementations use binary floating point. In binary floating-point, it is impossible to store any fractions that are not multiples of a negative power of two (½, ¼, ⅛, 1/16, 1/32, 1/64,…). So 1/100 cannot be exactly represented. Therefore, no matter what calculations you do, it is impossible to return exactly .01 or .79. The best you can do is get close.
When you perform arithmetic on floating-point numbers, the results are rounded to the nearest representable value. This means that, in x * 100, the result is, in generally, not exactly 100 times x. There is a small error due to rounding. This error cause push the value across the point where rounding changes from one direction to another, so it can make the answer wrong. There are techniques for avoiding this sort of error, but they are too complicated for introductory classes.
There is no need to convert to an integer to get truncation; C has a truncation function for floating-point built-in: trunc for double and truncf for float.
Additionally, the use of truncation in converting to integer compelled us to add ½ to get rounding instead. But, once we are no longer using a conversion to an integer type to get an integer value, we can use the built-in function for rounding floating-point values to integer values: round for double and roundf for float.
If your C implementation has good formatted input/output routines, then an easy way to find the value of a floating-point number rounded to the nearest hundred is to format it (as with snprintf) using the conversion specifier %.2f. A proper C implementation will convert the number to decimal, with two digits after the decimal point, using correct rounding that avoids the arithmetic rounding errors mentioned above. However, then you will have the number in string form.
Here are some hints:
Multiply float with "some power of 10" to ensure the needed precision numbers are shifted left
Cast the new value to a new int variable so the unwanted float bits are discarded
Divide the int by the same power of 10 but add use a float form of that (e.g 10.0) so integer gets converted to float and the new value is the correct value
To test, use printf with the precision (.2f)
The two most common methods of rounding are "Away From Zero" and "Banker's Rounding (To Even)".
Pseudo-code for Rounding Away From Zero
EDIT Even though this is pseudo-code, I should have included the accounting for precision, since we are dealing with floating-point values here.
// this code is fixed for 2 decimal places (n = 2) and
// an expected precision limit of 0.001 (m = 3)
// for any values of n and m, the first multiplicand is 10^(n+1)
// the first divisor is 10^(m + 1), and
// the final divisor is 10^(n)
double roundAwayFromZero(double value) {
boolean check to see if value is a negative number
add precision bumper of (1.0 / 10000) to "value" // 10000.0 is 10^4
multiply "value" by 1000.0 and cast to (int) // 1000.0 is 10^3
if boolean check is true, negate the integer to positive
add 5 to integer result, and divide by 10
if boolean check is true, negate the integer again
divide the integer by 100.0 and return as double // 100.0 is 10^2
ex: -123.456
true
-123.456 + (1.0 / 10000.0) => -123.4561
-123.4561 * 1000.0 => -123456.1 => -123456 as integer
true, so => -(-123456) => 123456
(123456 + 5) / 10 => 123461 / 10 => 12346
true, so => -(12346) => -12346
-12346 / 100.0 => -123.46 ===> return value
}
In your initial question, you expressed a desire for direction only, not the explicit answer in code. This is as vague as I can manage to make it while still making any sense. I'll leave the "Banker's Rounding" version for you to implement as an exercise.
Ok so I figured it out! thank yall for your answers.
//function
float rounding(float roundedNumber)
{
roundedNumber = roundedNumber * 100.0f + 0.5f;
roundedNumber = (int) roundedNumber * 0.01f;
return roundedNumber;
}
So pretty much if I entered 56.12567 as roundedNumber, it would multiply by 100 yielding 5612.567. From there it would add .5 which would determine if it rounds up. In this case, it does. The number would change to 5613.067.
Then you truncate it by converting it into a int and multiply by .01 to get the decimal back over. From there it returns the value to main and prints out the rounded number. Pretty odd way of rounding but I guess thats how you do it in C without using the rounding function.
Well, let's think about it. One thing that's helpful to know is that we can turn a float into an integer by casting:
float x = 5.4;
int y = (int) x;
//y is now equal to 5
When we cast, the float is truncated, meaning that whatever comes after the decimal point is dropped, regardless of its value (i.e. It always rounds towards 0).
So if you think about that and the fact that you care about the hundredths place, you could maybe imagine an approach that consists of manipulating your floating point number in someway such that when you cast it to an int you only truncate information you don't care about (i.e. digits past the hundredths place). Multiplying might be useful here.

Division of two floats giving incorrect answer

Attempting to divide two floats in C, using the code below:
#include <stdio.h>
#include <math.h>
int main(){
float fpfd = 122.88e6;
float flo = 10e10;
float int_part, frac_part;
int_part = (int)(flo/fpfd);
frac_part = (flo/fpfd) - int_part;
printf("\nInt_Part = %f\n", int_part);
printf("Frac_Part = %f\n", frac_part);
return(0);
}
To this code, I use the commands:
>> gcc test_prog.c -o test_prog -lm
>> ./test_prog
I then get this output:
Int_Part = 813.000000
Frac_Part = 0.802063
Now, this Frac_part it seems is incorrect. I have tried the same equation on a calculator first and then in Wolfram Alpha and they both give me:
Frac_Part = 0.802083
Notice the number at the fifth decimal place is different.
This may seem insignificant to most, but for the calculations I am doing it is of paramount importance.
Can anyone explain to me why the C code is making this error?
When you have inadequate precision from floating point operations, the first most natural step is to just use floating point types of higher precision, e.g. use double instead of float. (As pointed out immediately in the other answers.)
Second, examine the different floating point operations and consider their precisions. The one that stands out to me as being a source of error is the method above of separating a float into integer part and fractional part, by simply casting to int and subtracting. This is not ideal, because, when you subtract the integer part from the original value, you are doing arithmetic where the three numbers involved (two inputs and result) have very different scales, and this will likely lead to precision loss.
I would suggest to use the C <math.h> function modf instead to split floating point numbers into integer and fractional part. http://www.techonthenet.com/c_language/standard_library_functions/math_h/modf.php
(In greater detail: When you do an operation like f - (int)f, the floating point addition procedure is going to see that two numbers of some given precision X are being added, and it's going to naturally assume that the result will also have precision X. Then it will perform the actual computation under that assumption, and finally reevaluate the precision of the result at the end. Because the initial prediction turned out not to be ideal, some low order bits are going to get lost.)
Float are single precision for floating point, you should instead try to use double, the following code give me the right result:
#include <stdio.h>
#include <math.h>
int main(){
double fpfd = 122.88e6;
double flo = 10e10;
double int_part, frac_part;
int_part = (int)(flo/fpfd);
frac_part = (flo/fpfd) - int_part;
printf("\nInt_Part = %f\n", int_part);
printf("Frac_Part = %f\n", frac_part);
return(0);
}
Why ?
As I said, float are single precision floating point, they are smaller than double (in most architecture, sizeof(float) < sizeof(double)).
By using double instead of float you will have more bit to store the mantissa and the exponent part of the number (see wikipedia).
float has only 6~9 significant digits, it's not precise enough for most uses in practice. Changing all float variables to double (which provides 15~17 significant digits) gives output:
Int_Part = 813.000000
Frac_Part = 0.802083

C programming floating numbers?

So, I am reading a C prog. book and I read this exercise:
Write a program which asks the user to enter a dollars-and-cents amount, then displays the amount with 5% added?
Solution :
#include <stdio.h>
int main(void) {
float original_amount;
printf("Enter an amount: ");
scanf("%f", &original_amount);
printf("With tax added: $%.2f\n", original_amount * 1.05f);
return 0;
}
I know what .3f means (there should be 3 digits after...), but what does 1.05f mean?
The 1.05f does denote a floating point number with value approximately 1.05 (which is 105% = 100% + 5%). The %.2f is a format specifier and is something very different.
The multiplication with this number actually adds 5% to the value (value * 1.05 = value * (100% + 5%) = value + value * 5%).
Format specifiers occur in the first parameter of printf-like functions and tell the function how to output the argument corresponding to its position.
1.05f is a float type that has value 1.05
The program is apparently using multiplication by 1.05f as a way to add 5% to a number. But, because of representation error 1.05f is not exactly 1.05; it's a single-precsion floating point number close† to 1.05.
The float value closest to 1.05 is 1.0499999523162841796875 (assuming the usual 32-bit float format). Since you round the results you would have to use some fairly big numbers to see the effects of the error; try entering 100000000 when the program asks for amount:
Enter an amount: 100000000
With tax added: $104999992.00
If you used double precision instead of single precision, that is, double instead of float and 1.05 instead of 1.05f, the representation error would be smaller but it would still not be exactly 1.05, since this number cannot be represented exactly as the binary floating point numbers that our computers use.
You would get a correct result for 100000000, but still "incorrect" results for astronomically big numbers.
†) How close? From the standard:
For decimal floating constants, and also for
hexadecimal floating constants when
FLT_RADIX
is not a power of 2, the result is either
the nearest representable value, or the larger or smaller representable value immediately
adjacent to the nearest representable value, chosen in an implementation-defined manner.
It's the 5% part of your exercice. It's equal to: original_amout + (original_amout * 5.0 / 100.0).
it means 1.05 as float float you can take the f away it should work
printf has the prototype as int printf(const char *restrict format, ...);, it uses the const char *restrict format string to format the data printed.
You are confused between the format specifier %.2f which is passed as the 1st parameter to printf and the 1.05f passed as part of argument list. As you point out, first one is used for formatting. The argument list 1.05f is used for calculation purposes.The f indicates to the compiler you want to use a float or else by default it will be considered double datatype and the result of original_amount * 1.05f will be stored in a double.
It is sufficient to use a float when you know the number would fit in the float range.And to indicate this, you append a f to numbers in the argument list

Resources