views:

80

answers:

3

Is there a way in C++ to have it evaluate each floating point operation as a double even if the arguments are int? I have a program and numerous places I have code such as 1/2, 5/6. In these cases C++ casts the result to an int, that screws up the whole calculation. From the perspective of financial computations, are there other libraries besides 'cmath' that I could use that would contain more advanced functions.

+4  A: 

In these cases C++ casts the result to an int, that screws up the whole calculation

No, in these cases since both operands are integers you explicitly perform integer division; no casting takes place at all.

The correct answer would be to perform floating-point division:

1.0/2

It isn't that much extra effort to write the decimal point, is it?

James McNellis
I never knew you could just add a decimal without any fractional digits; that's handy
Michael Mrozek
It may be slightly easier to read if you add the 0 to make it 1.0
Martin York
@Martin: I was trying to show that one extra character wasn't much more work. But you're right of course; it's much easier to read as `1.0`.
James McNellis
I understand thats what I do. I understand the + operator applied on ints will result in an int. Just wondering if there was some macro some function in C++ that could do... obviously by design it cannot be done. 1.0/2 is not a lot of work but problem arises when you forget to make it float at certain places..
+3  A: 

In C (and thus C++) all builtin operators (ie POD) operato on objects of the same type. Thus if the parameters of a builtin operator have different types then the compiler will implicitly cast one (usually) of them (according to well defined rules) so that they are both the same. The result of the operator is also the same type as the input parameters.

What you are seeing is integer division which returns an integer.

The implicit casting rules:

1) If either value is long double then cast the other to long doubele  (technically only C)
2) If either value is      double then cast the other to      double
3) If either value is      float  then cast the other to      float
4) If either value is unsi long   then cast the other to unsi long
5) If either value is      long   then cast the other to      long
6) If either value is unsi int    then cast the other to unsi int
7) Cast both values to int

Note: All arithmatic operation are done on at least int. This means if both parameters are (u)short and/or char then they are both cast to int.

From this we can we can see that to get the operation to happen on doubles then at least one of the parameters must be a double in the code. To do this just add a fractional part to the expression.

int val = 1.0/2;

// This is equivalent to:

int val = static_cast<int>( 1.0 / static_cast<double>(2));
// Are you not glad the compiler does the implicit cast for you :-)
Martin York
A: 

Martin York has a good explanation of what is happening and James McNellis gives you a decent answer on what to do if you are using literals.

If you are using int/float/short/etc variables instead, then you can get around this by just casting them inline. e.g.

double Average(int *values, int count)
{
    int sum = 0;
    for(int i = 0; i < count; ++i) sum += values[i];
    return sum / (double) count; // Cast one of the values to double, that will force both to be calculated as doubles
    // note that "return (double)sum / count;" won't work because operator precendence
    // causes this to translate to "return (double)(sum / count);"

    // the "c++ way" to do this would be through the static_cast operator
    // i.e. "return static_cast<double>(sum)/count;"
    //  or  "return sum/static_cast<double>(count);"
    // both of which are very explicit in what you are casting
}
Grant Peters
I don't like the casting operator being used all over the place. In my case, it would make the code impossible to read and looong lines..