December 15, 2009 Re: Detecting inadvertent use of integer division | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bob Jones | Bob Jones wrote: > "Don" <nospam@nospam.com> wrote in message news:hg5nkk$1n37$1@digitalmars.com... >> bearophile wrote: >>> Don: >>>>> In Pascal too (and OCaML, but the situation is different) they are separated. I think here having two operators is better, >>>> Why? >>> You are intelligent and expert so you must know my answer, so I fear yours is a trick question :-) >> No, it's not a trick question. You've used Python extensively, I haven't. >> >>> Two operators allow to reduce the need for casts (and rounding/truncation), and are more explicit, allowing the code to express its meaning better to people that come after the original programmer. >> OK. I'm trying to get most of the benefits without needing an extra operator. > > Having made the switch from Delphi to C++ a few years ago I ran into this alot. I dislike that I have to litter my arithmetic expresions with casts in order to get the division operator to do what I want it to. And I suspect all of those who are used to having seperate intdiv & fltdiv operators will agree. Your arithmetic expressions would only become "littered with casts" if you regularly use integer division inside floating-point expressions. Personally, I cannot recall *ever* having intentionally used integer division inside a floating point expression. (I've seen inadvertent uses of it, plenty of times). > So using cast(int) to mean "actualy I did intend the integer division inside the following expression" instead of it's usual "convert this to" makes an ugly situation even more so imo. Well, it's really a bizarre situation. It's a very strange thing to be doing. > The fact that adding a specific intdiv operator would not only avoid more casting, but remove the the need for casting in a lot of existing cases I bet there are negligible cases where casting is required. > should count pretty well against the "no more operator/keywords" argument. Imo it should count enough to override it. > > But i guess cheap&ugly is more likely to make it in than expensive&expresive&ellegant. |
December 15, 2009 Re: Detecting inadvertent use of integer division | ||||
---|---|---|---|---|
| ||||
Posted in reply to Don | On Tue, 15 Dec 2009 03:02:01 -0500, Don <nospam@nospam.com> wrote:
> Phil Deets wrote:
>> On Mon, 14 Dec 2009 04:57:26 -0500, Don <nospam@nospam.com> wrote:
>>
>>> 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);
>> To me,
>> double y = cast(double)(1/x);
>> makes more sense. Why cast to int?
>
> That'd compile, too. But, it's pretty confusing to the reader, because that code will only set y == -1.0, +1.0, +0.0, -0.0, or else create a divide by zero error. So I'd recommend a cast to int.
I agree with Phil, in no situation that I can think of does:
T i, j;
T k = i/j;
U k = cast(T)i/j;
Make sense. I'd expect to see cast(U) there.
You can think of it as i/j returns an undisclosed type that implicitly casts to T, but not U, even if T implicitly casts to U.
Wow, this is bizarre.
I like the idea, but the recommendation to cast to int makes no sense to me. I'd also actually recommend this instead:
auto y = cast(double)(1/x);
On the idea as a whole, I think it's very sound. Note that the only case where it gets ugly (i.e. requiring casts) is when both operands of division are symbols, since it's trivial to turn an integer literal into a floating point.
-Steve
|
December 15, 2009 Re: Detecting inadvertent use of integer division | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Steven Schveighoffer wrote: > On Tue, 15 Dec 2009 03:02:01 -0500, Don <nospam@nospam.com> wrote: > >> Phil Deets wrote: >>> On Mon, 14 Dec 2009 04:57:26 -0500, Don <nospam@nospam.com> wrote: >>> >>>> 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); >>> To me, >>> double y = cast(double)(1/x); >>> makes more sense. Why cast to int? >> >> That'd compile, too. But, it's pretty confusing to the reader, because that code will only set y == -1.0, +1.0, +0.0, -0.0, or else create a divide by zero error. So I'd recommend a cast to int. > > I agree with Phil, in no situation that I can think of does: > > T i, j; > > T k = i/j; > U k = cast(T)i/j; > > Make sense. I'd expect to see cast(U) there. > > You can think of it as i/j returns an undisclosed type that implicitly casts to T, but not U, even if T implicitly casts to U. > > Wow, this is bizarre. Yeah. (However, mixing integer division with floating point is bizarre to start with. As I mentioned somewhere, I don't think I've ever actually seen it). > I like the idea, but the recommendation to cast to int makes no sense to me. I'd also actually recommend this instead: > > auto y = cast(double)(1/x); Fair enough, you won't see the recommendation to cast to int anywhere. But it doesn't really matter much. The important thing is, that by inserting *some* cast, you've drawn attention to the operation. Hopefully, the fact that you got a compiler error will inspire you to put a comment in the code, as well <g>. Personally, I'd always rewrite such a thing as: int z = 1/x; // Note: integer division!! double y = z; Completely separating the integer and floating-point parts. > On the idea as a whole, I think it's very sound. Note that the only case where it gets ugly (i.e. requiring casts) is when both operands of division are symbols, since it's trivial to turn an integer literal into a floating point. Exactly. And I think that's the situation where it happens in practice. Normally, integer literals can be used as floating point literals. This is the one case where integer and floating-point literals have a completely different meaning. |
December 15, 2009 Re: Detecting inadvertent use of integer division | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright wrote:
> Don wrote:
>> 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).
>
> That sounds like a very good idea.
I think the same (though I personally am not liable because it's been burned in my brain to always add ".0" to FP-involved literals). It's an improvement in the same vein as value range propagation.
Should we make this part of the language, or as a quality of implementation issue? I prefer the former, because the latter means that code compiles on one machine and doesn't on another.
Andrei
|
December 15, 2009 Re: Detecting inadvertent use of integer division | ||||
---|---|---|---|---|
| ||||
Posted in reply to Don | "Don" <nospam@nospam.com> wrote in message news:hg7gbm$1vln$1@digitalmars.com... > Bob Jones wrote: >> "Don" <nospam@nospam.com> wrote in message news:hg5nkk$1n37$1@digitalmars.com... >>> bearophile wrote: >>>> Don: >>>>>> In Pascal too (and OCaML, but the situation is different) they are separated. I think here having two operators is better, >>>>> Why? >>>> You are intelligent and expert so you must know my answer, so I fear yours is a trick question :-) >>> No, it's not a trick question. You've used Python extensively, I haven't. >>> >>>> Two operators allow to reduce the need for casts (and rounding/truncation), and are more explicit, allowing the code to express its meaning better to people that come after the original programmer. >>> OK. I'm trying to get most of the benefits without needing an extra operator. >> >> Having made the switch from Delphi to C++ a few years ago I ran into this alot. I dislike that I have to litter my arithmetic expresions with casts in order to get the division operator to do what I want it to. And I suspect all of those who are used to having seperate intdiv & fltdiv operators will agree. > > Your arithmetic expressions would only become "littered with casts" if you regularly use integer division inside floating-point expressions. Personally, I cannot recall *ever* having intentionally used integer division inside a floating point expression. (I've seen inadvertent uses of it, plenty of times). I grepped around 60 instances of double y = a / double(b); In my last project. That's what I'm talking about. Where you have to cast either top or bottom to float in order to get the division operator to do float division of two int operands. There's also the (perhaps MSVC specific) issue that I have to cast doubles to floats to get rid of the loss of precision warning message. It's a usuful warning on ints, but for floats it's completely redundant imo. >> The fact that adding a specific intdiv operator would not only avoid more casting, but remove the the need for casting in a lot of existing cases > > I bet there are negligible cases where casting is required. I didnt find any instances of an expresion containg intdiv being assigned to a float, so yeah, that is rare. But not the case where you have two ints and want the actual division done in float. |
December 15, 2009 Re: Detecting inadvertent use of integer division | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bob Jones | Bob Jones wrote: > "Don" <nospam@nospam.com> wrote in message news:hg7gbm$1vln$1@digitalmars.com... >> Bob Jones wrote: >>> "Don" <nospam@nospam.com> wrote in message news:hg5nkk$1n37$1@digitalmars.com... >>>> bearophile wrote: >>>>> Don: >>>>>>> In Pascal too (and OCaML, but the situation is different) they are separated. I think here having two operators is better, >>>>>> Why? >>>>> You are intelligent and expert so you must know my answer, so I fear yours is a trick question :-) >>>> No, it's not a trick question. You've used Python extensively, I haven't. >>>> >>>>> Two operators allow to reduce the need for casts (and rounding/truncation), and are more explicit, allowing the code to express its meaning better to people that come after the original programmer. >>>> OK. I'm trying to get most of the benefits without needing an extra operator. >>> Having made the switch from Delphi to C++ a few years ago I ran into this alot. I dislike that I have to litter my arithmetic expresions with casts in order to get the division operator to do what I want it to. And I suspect all of those who are used to having seperate intdiv & fltdiv operators will agree. >> Your arithmetic expressions would only become "littered with casts" if you regularly use integer division inside floating-point expressions. >> Personally, I cannot recall *ever* having intentionally used integer division inside a floating point expression. (I've seen inadvertent uses of it, plenty of times). > > I grepped around 60 instances of > > double y = a / double(b); > > In my last project. That's what I'm talking about. Where you have to cast either top or bottom to float in order to get the division operator to do float division of two int operands. OK, I misunderstood you. You're completely right. At least my proposal won't let them slip through silently. I don't think we can do anything else without silently breaking C compatibility. > There's also the (perhaps MSVC specific) issue that I have to cast doubles to floats to get rid of the loss of precision warning message. It's a usuful warning on ints, but for floats it's completely redundant imo. > > >>> The fact that adding a specific intdiv operator would not only avoid more casting, but remove the the need for casting in a lot of existing cases >> I bet there are negligible cases where casting is required. > > I didnt find any instances of an expresion containg intdiv being assigned to a float, so yeah, that is rare. But not the case where you have two ints and want the actual division done in float. |
December 15, 2009 Re: Detecting inadvertent use of integer division | ||||
---|---|---|---|---|
| ||||
Posted in reply to Don | Don: > Bob Jones: > > double y = a / double(b); > OK, I misunderstood you. You're completely right. At least my proposal won't let them slip through silently. I don't think we can do anything else without silently breaking C compatibility. A silly idea that may keep C compatibility and avoid that cast: instead of an integer division operator it can be added a operator that always performs a floating point division, as: int a = 5, b = 7; double y = a \\ b; (I don't like that much, Pascal is better here). Bye, bearophile |
December 15, 2009 Re: Detecting inadvertent use of integer division | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Dec 16, 09 05:14, bearophile wrote:
> Don:
>
>> Bob Jones:
>>> double y = a / double(b);
>
>> OK, I misunderstood you. You're completely right. At least my proposal
>> won't let them slip through silently. I don't think we can do anything
>> else without silently breaking C compatibility.
>
> A silly idea that may keep C compatibility and avoid that cast: instead of an integer division operator it can be added a operator that always performs a floating point division, as:
> int a = 5, b = 7;
> double y = a \\ b;
> (I don't like that much, Pascal is better here).
>
> Bye,
> bearophile
Just introduce real fdiv(real, real) (or /fdiv/) if this is the solution. Works right now without changing the language.
|
December 15, 2009 Re: Detecting inadvertent use of integer division | ||||
---|---|---|---|---|
| ||||
Posted in reply to KennyTM~ | "KennyTM~" <kennytm@gmail.com> wrote in message news:hg90tu$22od$1@digitalmars.com... > On Dec 16, 09 05:14, bearophile wrote: >> Don: >> >>> Bob Jones: >>>> double y = a / double(b); >> >>> OK, I misunderstood you. You're completely right. At least my proposal won't let them slip through silently. I don't think we can do anything else without silently breaking C compatibility. >> >> A silly idea that may keep C compatibility and avoid that cast: instead >> of an integer division operator it can be added a operator that always >> performs a floating point division, as: >> int a = 5, b = 7; >> double y = a \\ b; >> (I don't like that much, Pascal is better here). >> >> Bye, >> bearophile > > Just introduce real fdiv(real, real) (or /fdiv/) if this is the solution. Works right now without changing the language. Reserving the only division operator for intdiv-only for the sake of C compatibility would be terrible design. |
December 15, 2009 Re: Detecting inadvertent use of integer division | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | Nick Sabalausky:
> Reserving the only division operator for intdiv-only for the sake of C compatibility would be terrible design.
Well, no, the (silly) idea is:
int / int => int
int \\ int => float
float / int => float
float \\ int => float
int / float => float
int \\ float => float
float / float => float
float \\ float => float
So the / is not just the int division. The only difference between the two operators is when you have (int,int).
Bye,
bearophile
|
Copyright © 1999-2021 by the D Language Foundation