Detecting inadvertent use of integer division
Walter Bright
newshound1 at digitalmars.com
Mon Dec 14 02:17:34 PST 2009
Don wrote:
> Consider this notorious piece of code:
>
> assert(x>1);
> double y = 1 / x;
>
> This calculates y as the reciprocal of x, if x is a floating-point
> number. But if x is an integer, an integer division is performed instead
> of a floating-point one, and y will be 0.
>
> It's a very common newbie trap, but I find it still catches me
> occasionally, especially when dividing two variables or compile-time
> constants.
>
> In the opPow thread there were a couple of mentions of inadvertent
> integer division, and how Python is removing this error by making /
> always mean floating-point division, and introducing a new operator for
> integer division.
>
> We could largely eliminate this type of bug without doing anything so
> drastic. Most of the problem just comes from C's cavalier attitude to
> implicit casting. All we'd need to do is tighten the implicit conversion
> rules for int->float, in the same way that the int->uint rules have been
> tightened:
>
> "If an integer expression has an inexact result (ie, involves an inexact
> integer divison), that expression cannot be implicitly cast to a
> floating-point type."
But the compiler cannot reliably tell if it will produce an inexact result.
> (This means that double y = int_val / 1; is OK, and also:
> double z = 90/3; would be OK. An alternative rule would be:
> "If an integer expression involves integer divison, that expression
> cannot be implicitly cast to a floating-point type").
This is kinda complicated if one has, say:
double z = x/y + 3;
> In the very rare cases where the result of an integer division was
> actually intended to be stored in a float, an explicit cast would be
> required. So you'd write:
> double y = cast(int)(1/x);
>
> Like the implicit uint->int casts which have recently been disallowed, I
> think this would prevent a lot of bugs, without causing much pain.
Maybe it's easier to simply disallow 1/x, where x is an int, and the
numerator is '1'. But then maybe that will cause problems with generic
code. I don't think there's an easy answer here.
More information about the Digitalmars-d
mailing list