-4

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
ycohui
  • 66
  • 7
  • 1
    Cast one of the arguments to float (or double) - 7.0, or `(float)input` will both work. – kabanus May 09 '22 at 04:32
  • 1
    ycohui, Tip: save time and enable all warnings to quickly find the problem with `printf("Output: %f", (input / 7);`. – chux - Reinstate Monica May 09 '22 at 04:44
  • @kabanus Curious, why suggest a cast to `float` and not `double`? – chux - Reinstate Monica May 09 '22 at 04:46
  • @chux-ReinstateMonica why not? – kabanus May 09 '22 at 05:09
  • @ kabanus, @ chux-reinstate-monica thanks, will try to run in a sec. Anyone could tell me why i am getting downvoted for the question? What shall I changed / edit for the "standard"? – ycohui May 09 '22 at 05:14
  • 1
    I'm not one of your downvotes, but I suspect the reason is that integer division is probably as common a question as the misuse of `scanf()` is by new C programmers. So the site already contains hundreds (if not thousands) of answer related to integer division. That's my best guess. Search `"[c] integer division"` and you will have your pick of answers. – David C. Rankin May 09 '22 at 06:20
  • 2
    I was tempted to add a downvote because you have been here long enough to know that you should copy/paste **real, actual code** not "something like" your code. It would not have compiled, and if corrected it could not have output the stated result. But there are enough. – Weather Vane May 09 '22 at 06:42
  • @WeatherVane This is the actual code that i tried, as following divide and conquer method to learn C. I **had** actually compiled it, compiler might be not fully correctly setup such there is no error stated by the compiler. These made me confused and such asked these newbie question. Anyways, thanks for your kindly replied. – ycohui May 09 '22 at 10:57
  • @kabanus `printf("Output: %f", ((float) input / 7);`, `(input / (float)7)` and `(input / 7.0f)`, as you [suggest](https://stackoverflow.com/questions/72166998/c-int-arithmetic-calculation-with-float-beginner?noredirect=1#comment127507994_72166998) all convert the `int input` to `float`, perform a `float` division, and then convert the quotient to `double` as part of a `...` argument. This 2 step FP conversion vs. the one step `((double) input / 7)` or `(input / 7.0)` disadvantages include: more complicated and loses observable precision for large `input`. Why suggest `float`? – chux - Reinstate Monica May 09 '22 at 11:54
  • I stand by what I wrote: `printf("Output: %f", (input / 7);` has a syntax error. The code *does not compile*, and even if it did, it does not produce what you say, but quite different messages. – Weather Vane May 09 '22 at 15:39

2 Answers2

1

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?

c.fogelklou
  • 1,781
  • 1
  • 13
  • 26
  • Why convert `int` to `float` and then `float` to `double` instead of [one conversion](https://stackoverflow.com/questions/72166998/c-int-arithmetic-calculation-with-float-beginner?noredirect=1#comment127515698_72166998) with `input / 7.0`? – chux - Reinstate Monica May 09 '22 at 11:57
1
  • 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.)

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Advanced topic detail: Using `float` loses precision of the `int` with large `int`. Also to avoid the `float` to `double` extra step, use `double f_input = (double)input;` – chux - Reinstate Monica May 09 '22 at 12:02
  • @chux-ReinstateMonica Well, maybe the requirement is to use single precision. Then an explicit conversion to `double` doesn't make sense. Why variadic functions in general come with weird implicit promotions is another story. Some mid-range CPUs may not have double precision available - or only have it available as software floating point libs. – Lundin May 09 '22 at 14:23
  • Readers should ignore the advice in this question to use a cast to remove an implicit conversions. Casts are necessary in some places, such as bitwise operations where you need to ensure an unsigned type of the appropriate width is used rather than the `int` that results from the default integer promotion. In this situation, casting to `float` neither makes the code correct (the conversion to the desired type, `float`, will occur in an assignment to `float` or a division by a `float`) nor helps avoid errors (and may conceal an error because a cast can force a conversion… – Eric Postpischil May 10 '22 at 11:31
  • … that is not allowed implicitly, so you lose some of the error-checking a compiler will normally do). (Also, although the answer first states all implicit conversions have been removed and then admits the `float` argument is converted to `double`, there are actually five implicit conversions in those three lines of code.) – Eric Postpischil May 10 '22 at 11:32
  • @EricPostpischil The reason why implicit conversions should be avoided is simply because they might contain unexpected changes in type or signedness. The compiler can't help you there, because it does all implicit conversions quietly. – Lundin May 10 '22 at 12:01
  • It's better to explicitly document that you know what you are doing, instead of writing stuff like `1 + 1.0f / 2 - 1.0` and then expect everyone including yourself to keep track of all the implicit promotions in that expression. Or worse: write such crap on purpose for the sake of posing about one's implicit promotion knowledge. A frightening amount of C programmers actually don't have a clue about most implicit promotions (and even fail to use `f` suffix for `float`) so the correct approach is to convert everything to the _intended_ type before the expression. – Lundin May 10 '22 at 12:02
  • @Lundin: Changing `x` to `(t) x` does not solve the problem that an implicit conversion might convert it to unexpected type or signedness, because `(t) x` is subject to the same operand rules that `x` is. And compilers do not do all implicit conversions quietly; common compilers have warnings for hazardous implicit conversions. One can document what they are doing by stating it in comments. – Eric Postpischil May 10 '22 at 12:24
  • @Lundin: Re “A frightening amount of C programmers actually don't have a clue about most implicit promotions”: Yes, I see; as regarding the “all of the implicit promotions in that expression” for `1 + 1.0f / 2 - 1.0`, there are no (non-null) implicit promotions. `1` and `2` are `int`, so the integer promotions have no effect, and there is no function call for the default argument promotions to apply. The usual arithmetic conversions will convert `1 + 1.0f / 2` to `double`, but inserting `(float)` anywhere in that will not alter that. – Eric Postpischil May 10 '22 at 12:29
  • So you are just recommending complicating something you say people have trouble with with more complications. That is just posturing, not good engineering. – Eric Postpischil May 10 '22 at 12:31
  • @EricPostpischil Or you could simply never mix integer and floating point in the same expression, which is what you are arguing against here. In case of constants there's no need for a cast, simply do `1.0f + 1.0f / 2.0f - 1.0f`. This is self-documenting code without the need to ponder precedence, associativity and implicit promotions. – Lundin May 10 '22 at 12:32
  • I have not argued against mixing integer and floating-point. I have simply informed readers they may ignore the “advice” about inserting casts to avoid implicit casts. It is not generally helpful outside of bit-manipulation operations. – Eric Postpischil May 10 '22 at 12:46
  • @EricPostpischil It can be helpful when doing the opposite: ensuring that no floating point calculations are present. Some examples would be `int x = pow(2,10);` or `int y = 2e3;`. In both of these cases, a half-decent compiler will make the machine code boil down an integer constant. And yet there's a bunch of implicit (lvalue) conversions which in turn might result in false positive compiler warnings. One way to avoid such warnings could be to hide the expressions inside macros where everything is cast explicitly. – Lundin May 10 '22 at 13:05
  • @Lundin: Fine, if there is a particular situation where you want to silence compiler warnings, use casts. It is just using them habitually that is not generally helpful and that may suppress useful warning messages. – Eric Postpischil May 10 '22 at 23:48