C - int arithmetic calculation with float (beginner) - c

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?

Related

Mathematical operation on macro value in C

The output of the following program is T = 0.0000.
#include <stdio.h>
#include <math.h>
#define Fs 8000
int main()
{
float T = 1/Fs;
printf("T = %f", T);
return 0;
}
However, when the macro Fs is declared as a float variable inside main, I get the correct output T = 0.000125. Can anyone explain what is going on? Is it possible to get the correct output with the macro too?
#include <stdio.h>
#include <math.h>
int main()
{
float Fs = 8000;
float T = 1/Fs;
printf("T = %f", T);
return 0;
}
Integer divided by integer = integer. Integer divided by float = float.
Either:
#define Fs 8000.0
and/or
float T = 1.0/Fs;
and/or
float T = 1/(float)(Fs);
Can anyone explain what is going on?
In C the type used by an operator is picked based on that operator's operands and not based on the type where you store the result.
Also everything including constants has a type. 8000 is type int, 8000.0 is type double and 8000.0f is type float.
In case of 1/Fs with Fs as a macro for the integer 8000, then both operands of the division are int. Therefore the division is carried out on int type and you get the result 0 because of it.
In case of 1/Fs with Fs as type float, one operand of the division is int and the other is float. Something called "the usual arithmetic conversions" (see Implicit type promotion rules) then "promotes" the int to type float. The division is carried out on float type.
Some best practices:
Avoid mixing integers/int constants with floating point arithmetic. Instead write every expression involving floating point with pure floating point constants/variables.
Use 8000.0f when dealing with float and 8000.0 when dealing with double.
float is a type that should barely ever be used in C programs and never in beginner programs. The only scenario where you should ever use float is when your CPU has a single precision FPU but no hardware support for double precision - which is a very specific scenario and not applicable to modern x86 PC where double should be used everywhere.
Avoid writing code relying on implicit type promotions. If correct types are used from the start, such promotions can be avoided.

type of numbers that are not stored in a variable [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 4 years ago.
I'm a Little confused about some numbers in C-Code. I have the following piece of Code
int k;
float a = 0.04f;
for (k=0; k*a < 0.12; k++) {
* do something *
}
in this case, what is the type of "0.12" ? double ? float ? it has never been declared anywhere. Anyways, in my program the Loop above is excuted 4 times, even though 3*0.04=0.12 < 0.12 is not true. Once I Exchange 0.12 with 0.12F (because I am globally restricted to float precision in all of the program), the Loop is now executed 3 times. I do not understand why, and what is happening here. Are there any proper Guidelines on how to write such statements to not get unexpected issues?
Another related issue is the following: in the Definition of variables, say
float b = 1/180 * 3.14159265359;
what exactly "is" "1" in this case ? and "180" ? Integers ? Are they converted to float numbers ? Is it okay to write it like that ? Or should it be "1.0f/180.0f*3.14159265359f;"
Last part of the question,
if i have a fuction
void testfunction(float a)
which does some things.
if I call the fuction with testfunction(40.0/6.0), how is that Division handled ? It seems that its calculated with double precision and then converted to a float. Why ?
That was a Long question, I hope someone can help me understand it.
...numbers that are not stored in a variable
They are called "constants".
Any unsuffixed floating point constant has type double.
Quoting C11, chapter §6.4.4.2
An unsuffixed floating constant has type double. If suffixed by the letter f or F, it has
type float. If suffixed by the letter l or L, it has type long double.
For Integer constants, the type will depend on the value.
Quoting C11, chapter §6.4.4.1,
The type of an integer constant is the first of the corresponding list in which its value can
be represented. [..]
and for unsuffixed decimal number, the list is
int
long int
long long int
Regarding the mathematical operation accuracy of floating point numbers, see this post
"0.12" is a constant, and yes, without a trailing f or F, it will be interpreted as a double.
That number can not be expressed exactly as a binary fraction. When you compare k * a, the result is a float because both operands are floats. The result is slightly less than 0.12, but when you compare against a double, it gets padded out with zeros to the required size, which increases the discrepancy. When you use a float constant, the result is not padded (cast), and by good luck, comes out exactly equal to the binary representation of "0.12f". This would likely not be the case for a more complicated operation.
if we use a fractional number for eg, like 3.4 it's default type if double. You should explicitly specify it like 3.4f if you want it to consider as single precision (float).
if you call the following function
int fun()
{
float a= 1.2f;
double b = 1.2;
return (a==b);
}
this will always return zero (false).because before making comparison the float type is converted to double (lower type to higher type) , At this time sometimes it can't reproduce exact 1.2, a slight variations in value can be happen after 6th position from decimal point. You can check the difference by the following print statement
printf("double: %0.9f \n float: %0.9f\n",1.2,1.2f);
It results ike
double: 1.200000000
float: 1.200000481

How can I fix my floats being rounded down to doubles?

I know that by default in C when you declare a float it gets automatically saved as a double and that if you want it to be saved as a float you have to declare it like this
float x = 0.11f
but what if my x value comes from a scanf? How can I do so that when I print it it doesn't get rounded down or up?
Here's my code btw, thanks for the help.
#include <stdio.h>
int main() {
float number = 0;
float comparison;
do{
printf("\nEnter a number: ");
scanf("%f", &comparison);
if(comparison > number) {
number = comparison;
}
}while(comparison > 0);
printf("The largest number enteres was: %f\n\n", number);
}
what if my x value comes from a scanf? How can I do so that when I print it it doesn't get rounded down or up?
scanf with an %f directive will read the input and convert it to a float (not a double). If the matched text does not correspond to a number exactly representable as a float then there will be rounding at this stage. There is no alternative.
When you pass an argument of type float to printf() for printing, it will be promoted to type double. This is required by the signature of that function. But type double can exactly represent all values of type float, so this promotion does not involve any rounding. printf's handling of the %f directives is aligned with this automatic promotion: the corresponding (promoted) argument is expected to be of type double.
There are multiple avenues to reproducing the input exactly, depending on what constraints you are willing to put on that input. The most general is to read, store, and print the data as a string, though even this has its complications.
If you are willing to place a limit on the maximum decimal range and precision for which verbatim reproduction is supported, then you may be able to get output rounded to the same representation as the input by specifying a precision in your printf field directives:
float f;
scanf("%f", &f);
printf("%f %.2f %5.2f\n", f, f, f);
If you want to use a built-in floating-point format and also avoid trailing zeroes being appended then either an explicit precision like that or a %g directive is probably needed:
printf("%f %g\n", f, f);
Other alternatives are more involved, such as creating a fixed-point or arbitrary-precision decimal data type, along with appropriate functions for reading and writing it. I presume that goes beyond what you're presently interested in doing.
Note: "double" is short for "double precision", as opposed to notionally single-precision "float". The former is the larger type in terms of storage and representational capability. In real-world implementations, there is never any "rounding down" from float to double.

Time = distance over speed in 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.

Handling numbers in C

Couldnt understand how numbers are handled in C. Could anyone point to a good tutorial.
#include<stdio.h>
main()
{
printf("%f",16.0/3.0);
}
This code gave: 5.333333
But
#include<stdio.h>
main()
{
printf("%d",16.0/3.0);
}
Gave some garbage value: 1431655765
Then
#include<stdio.h>
main()
{
int num;
num=16.0/3.0;
printf("%d",num);
}
Gives: 5
Then
#include<stdio.h>
main()
{
float num;
num=16/3;
printf("%f",num);
}
Gives: 5.000000
printf is declared as
int printf(const char *format, ...);
the first arg (format) is string, and the rest can be anything. How the rest of the arguments will be used depending on the format specifiers in format. If you have:
printf("%d%c", x, y);
x will be treated as int, y will be treated as char.
So,
printf("%f",16.0/3.0);
is ok, since you ask for float double (%f), pass float double(16.0/3.0)
printf("%d",16.0/3.0);
you ask for int(%d), you pass float double (double and int have different internal representation) so, the bit representation of 16.0/3.0 (double) corresponds to bit representation of 1431655765(int).
int num;
num=16.0/3.0;
compiler knows that you are assigning to int, and converts it for you. Note that this is different than the previous case.
Ok, the first 1 is giving correct value as expected.
Second one you are passing a float while it is treating it as an int (hence the "%d" which is for displaying int datatypes, it is a little complicated to explain why and since it appears your just starting I wouldn't worry about why "%d" does this when passed a float) reading it wrong therefore giving you a wierd value. (not a garbage value though).
Third one it makes 16.0/3.0 an int while assigning it to the int datatype which will result in 5. Because while making the float an int it strips the decimals regardless of rounding.
In the fourth the right hand side (16/3) is treated as an int because you don't have the .0 zero at the end. It evaluates that then assigns 5 to float num. Thus explaining the output.
It is because the formatting strings you are choosing do not match the arguments you are passing. I suggest looking at the documentation on printf. If you have "%d" it expects an integer value, how that value is stored is irrelevant and likely machine dependent. If you have a "%f" it expects a floating point number, also likely machine dependent. If you do:
printf( "%f", <<integer>> );
the printf procedure will look for a floating point number where you have given an integer but it doesn't know its and integer it just looks for the appropriate number of bytes and assumes that you have put the correct things there.
16.0/3.0 is a float
int num = 16.0/3.0 is a float converted to an int
16/3 is an int
float num = 16/3 is an int converted to a float
You can search the web for printf documentation. One page is at http://linux.die.net/man/3/printf
You can understand numbers in C by using concept of Implecit Type Conversion.
During Evaluation of any Expression it adheres to very strict rules of type Conversion.
and your answer of expression is depends on this type conversion rules.
If the oparands are of different types ,the 'lower' type is automatically converted into the 'higher' type before the operation proceeds.
the result is of the higher type.
1:
All short and char are automatically converted to int then
2:
if one of the operands is int and the other is float, the int is converted into float because float is higher than an ** int**.
if you want more information about inplicit conversion you have to refer the book Programming in ANSI C by E Balagurusamy.
Thanks.
Bye:DeeP
printf formats a bit of memory into a human readable string. If you specify that the bit of memory should be considered a floating point number, you'll get the correct representation of a floating point number; however, if you specify that the bit of memory should be considered an integer and it is a floating point number, you'll get garbage.
printf("%d",16.0/3.0);
The result of 16.0/3.0 is 5.333333 which is represented in Single precision floating-point format as follows
0 | 10101010 | 10101010101010101010101
If you read it as 32bit integer value, the result would be 1431655765.
num=16.0/3.0;
is equivalent to num = (int)(16.0/3.0). This converts the result of float value(5.33333) to integer(5).
printf("%f",num);
is same as printf("%f",(float)num);

Resources