Detecting inadvertent use of integer division
Jason House
jason.james.house at gmail.com
Mon Dec 14 20:12:11 PST 2009
Don Wrote:
> Walter Bright wrote:
> > 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;
>
> Integer expressions remain inexact until there's a cast.
>
> (It's very simple to implement, you just use the integer range code,
> adding an 'inexact' flag. Division sets the flag, casts clear the flag,
> everything else just propagates it if a unary operation, or ORs the two
> flags if a binary operation).
What about function calls?
double z = abs(x/y);
Regardless, your proposal is a simple incremental improvement, and I'd love to see it in D.
Also, one more thought: should similar rigor be used for implicit float -> double conversions?
More information about the Digitalmars-d
mailing list