#include <stdio.h>

int main()
{
 int iBAF=10;
 int iPlots=14;
 double dblFactor;

 dblFactor=iBAF/iPlots;   //to get a floating point you need a cast!
 printf("dblFactor = %10.6f\n",dblFactor);

 return 0;
}

/*
dblFactor =   0.000000
*/

I thought C/C++ would offer a few benifits beyond pure assembler. Apparently I was wrong.

Recommended Answers

All 8 Replies

You don't like how C defines integer division, and from that you conclude that it has no advantages over assembly language? Surely you're joking!

#include <stdio.h>

int main()
{
 int iBAF=10;
 int iPlots=14;
 double dblFactor;

 dblFactor=iBAF/iPlots;   //to get a floating point you need a cast!
 printf("dblFactor = %10.6f\n",dblFactor);

 return 0;
}

/*
dblFactor =   0.000000
*/

I thought C/C++ would offer a few benifits beyond pure assembler. Apparently I was wrong.

A CPU can operate on an integer faster than it can a floating-point number. As a result, there are 2 main definitions of the division operator. Integer division, which is very quick, and floating-point, which isn't as quick.

What you have written requests integer division because both operands are defined as integers. As a result, this is normal behavior. To get a floating-point return value without a cast, one of the operands must be a floating-point type so that floating-point division is requested. To understand it a little more, you may want to read about operator overloading.

This produces the same result as your example (truncation of fractional/decimal portion):

int main() {
  double integerDivisionQuotient = 0.0;

  //perform integer division
  integerDivisionQuotient = 5/2;  //integerDivisionQuotient now contains 2

  return 0;
}

To correct it, you must request floating point division:

int main() {
  double floatingPointQuotient = 0.0;

  //perform floating-point division
  floatingPointQuotient = 5.0/2;  //floatingPointQuotient now contains 2.5
  //notice the ".0" added to the 5...

  return 0;
}

I just wouldn't have thought a cast would be necessary to assign the results of a division to a floating point variable irregardless of the variable types involved in the division. I'd have expected truncation if the result would be assigned to an integer; but not with a float.

Yes, I see now. In your example you are using hard coded literals, i.e., 5.0, etc. In my actual program where this bit me (complex code and it took me a good hour to track it down) I have all variables. Here is the actual statement which was giving me zeros for everything...

dblFactor = ptrMainWindowData->ConfigData.BAF / iPlots; //both integers

I'm not new to C++; I guess I don't use floating points very much; mostly GUI code. It just really astounded me to see that.

An assignment is not a cast. The compiler pays very little attention to the type of the variable on the left side of an assignment statement until the assignment actually begins. All that it does is verify that the type of the value being placed in the variable is compatible with the receiving variable's type. If it is compatible, a "promotion" may be performed for formatting purposes (see below).

In the situation in question, the decimal is truncated even before the assignment operation begins because the signature of the requested operator's function is int operator/(int,int); The signature of the operator function you want is double operator/ (double, double); . To get it, one of the operators must be a non-integer (floating-point) type. This works because of the compiler's ability to "promote" a value to another, more detailed, type. A promotion is nothing more than a reformatted copy of existing data, it is not a cast. You can't copy information that doesn't exist.

EDIT:
oops, looks like we overlapped... I think you may have already realized what I was trying to say here.

I thought C/C++ would offer a few benifits beyond pure assembler. Apparently I was wrong.

Languages that don't have this behavior make a great many common programming tasks harder, not easier.

The compiler pays very little attention to the type of the variable on the left side of an assignment statement until the assignment actually begins.

That does appear to be about the best description of the situation. Your constant mentioning of the operator overloading issue (obviously different code is being generated for the different situations) prompted me to check out what happens in the case of compiling as a C program but the outcome was the same.

After I discovered what was happening in my code and that I could solve the problem by casting either of the parameters (divisor??? dividend??? - my memory fails me!), I thought a more correct cast would be this...

dblFactor = (double)(iNum1 / iNum2);

...but of course that failed too for the reasons you described; 1st a truncation to zero then the assignment of the zero to dblFactor. As you say, the compiler is looking for a double in either the top or bottom or both.

Oh well, now I know!

I would have been surprised if that worked. You are correct, more appropriate casts would be:

floatingPointQuotient = ((double) integerNumerator / integerDenominator)

floatingPointQuotient = (integerNumerator / (double) integerDenominator)

floatingPointQuotient = ((double) integerNumerator / (double) integerDenominator)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.