6

Ran across this in code I'm working through:

double part2 = static_cast<double>(2) * somthing1
  * ( static_cast<double>(1) + something2 )
  + ( static_cast<double>(1) / static_cast<double>(2) ) * something3
  + ( static_cast<double>(1) / static_cast<double>(2) ) * pow ( something4, 3 );

(The somethings are doubles.)

I suspect that there's a really good reason for going through the trouble of doing

static_cast<double>(1)

and the like, but it seems like I could get by with a lot less typing.

What am I not understanding?

Thanks in advance.

John
  • 15,990
  • 10
  • 70
  • 110
  • 4
    Yes, it would be a lot simpler to type `2.0` or `2.` No idea why one would want to cast literals. - One might also have a false idea that both operands **need** to be doubles in a binary operator call (either one is enough). – UncleBens Mar 23 '11 at 22:18
  • You can always use short literals: http://stackoverflow.com/questions/208433/how-do-i-write-a-short-literal-in-c and leave explicit casts for variables. – AJG85 Mar 23 '11 at 22:22
  • 3
    This is a great example to illustrate you should always write your code as short and simple as possible. If you don't, people start assuming there's a reason you didn't type it the simple way, and they dare not change it. –  Mar 23 '11 at 22:29
  • @jdv, yes, that's exactly the feeling I got. :) – John Mar 23 '11 at 22:39

3 Answers3

7

Many of these static_casts are unnecessary, because of automatic numeric promotion. The ones that are extremely necessary are the ones used on constructing the number 1/2, although in this case there's no obvious reason not to just say 0.5 instead. In any case a compiler that's paying attention will remove all of these and replace them with compile-time constants.

Paul Z
  • 872
  • 4
  • 8
  • 1
    Are there any pitfalls for just doing (1.0 / 2.0) instead? Isn't that a `double`? (The purpose for doing that instead of just writing 0.5 would be, presumably, to maintain parallel structure with the scholarly journal the original programmer is referencing.) – John Mar 23 '11 at 22:23
  • Not really. Most compilers will make it a `float` by default, but since both numbers as well as their quotient can be represented exactly, it doesn't really matter. And a decent compiler will still replace `(1.0 / 2.0)` with `0.5`. – Paul Z Mar 23 '11 at 22:27
  • @John: `(1.0 / 2.0)` would work just as well and be a big readability improvement over throwing static_cast all over the place. But as Paul mentions, there's nothing too mysterious about using `0.5` directly (at least it's no more mysterious than `(1.0 / 2.0)`) – Michael Burr Mar 23 '11 at 22:27
  • 7
    the type of a floating literal is `double` unless explicitly specified by a suffix. – Mike Seymour Mar 23 '11 at 22:31
2

I agree with the previous answer that 2.0 would be much better here.

However, I found another red flag in the code, namely pow(something, 3). The pow function is designed to take two arbitrary values, x and y and return x^y. As this function must handle arbitrary values, it will do an approximation. However, this 1) is complex to calculate and 2) sometimes miss the mark. In this case, you would be much better of simply using something4 * something4 * something4.

Lindydancer
  • 25,428
  • 4
  • 49
  • 68
1

This is equivalent to the much more readable

double part2 = 2 * somthing1 * (1 + something2)
  + 0.5 * something3 + 0.5 * something4 * something4 * something4

since integers are promoted to doubles each time an arithmetic operation has one double operand. The 0.5 double litteral is enough to promote everything to double.

Alexandre C.
  • 55,948
  • 11
  • 128
  • 197
  • 1
    I think that your answer is insufficient. What if `something2` is `UINT_MAX`? Try `double part2 = 2 * somthing1 * (1. + something2) + 0.5 * something3 + 0.5 * something4 * something4 * something4;` – Robᵩ Mar 23 '11 at 22:43
  • @Rob: So the purpose of that change would be to promote `something2` to a `double` before it causes problems if it were an `unsigned int` with value `UINT_MAX`? – John Mar 23 '11 at 22:50
  • 1
    @John: Yes. `1 + UINT_MAX == 0`, but `1.0 + UINT_MAX != 0`. – Robᵩ Mar 23 '11 at 22:54
  • The question says "The somethings are doubles." So this answer is right. (Although personally I would prefer writing 2.0 and 1.0, just in case the types of something1 and something2 change in future). – user9876 Jul 06 '11 at 12:47