D - double to int conversion
- Derek Parnell (22/22) Apr 01 2004 Walter,
- Walter (12/32) Apr 02 2004 You make a good argument for that case. However, I decided against the C...
- Derek Parnell (54/94) Apr 02 2004 Foo
- J Anderson (25/78) Apr 02 2004 But the programmer has the option with casting, its just that in most
- Derek Parnell (34/98) Apr 02 2004 an
- J Anderson (12/64) Apr 02 2004 a is a character.
- Walter (24/46) Apr 02 2004 The underlying thing going on here is that the C integral promotion rule...
- Derek Parnell (17/65) Apr 02 2004 Thank you Walter. You have given excellent answers here. I can understan...
- Walter (5/8) Apr 02 2004 someday
- Matthias Becker (4/11) Apr 04 2004 I proved that dmd doesn't follow this rule (haven't tested with the curr...
- Walter (6/10) Apr 04 2004 current
- J C Calvarese (13/27) Apr 04 2004 I don't know that Walter changed anything. Perhaps he already fixed the
Walter, as I understand it, I can get this message "constructor this overloads Foo (int x) and Foo (double x) both match argument list for this" when I have defined ... this(int x) { ... } this(double x) { ... } and I then try to do this ... Foo a = new Foo('D'); Which means that the compiler has decided that the literal character 'D' could be either an integer or a double and therefore the coder must make the call explicit. So my question is - how often have you even seen a coder write a literal character down to mean a double (floating point) value? I would have thought that the overwhelming practice is that a literal character represents an integer and if a coder really needs it to be a double they would explicitly cast it as such... double x = cast(double)'D'; With the current D implementation, the coder nearly always has to do more work now than they used to do (for the same idiom) in C/C++/Java/whatever... -- Derek
Apr 01 2004
"Derek Parnell" <Derek.Parnell psyc.ward> wrote in message news:opr5tcocfiu2m3b2 news.digitalmars.com...Walter, as I understand it, I can get this message "constructor this overloads Foo (int x) and Foo (double x) both match argument list for this" when I have defined ... this(int x) { ... } this(double x) { ... } and I then try to do this ... Foo a = new Foo('D'); Which means that the compiler has decided that the literal character 'D' could be either an integer or a double and therefore the coder must make the call explicit. So my question is - how often have you even seen a coder write a literal character down to mean a double (floating point) value? I would have thought that the overwhelming practice is that a literal character represents an integer and if a coder really needs it to be a double they would explicitly cast it as such... double x = cast(double)'D'; With the current D implementation, the coder nearly always has to do more work now than they used to do (for the same idiom) in C/C++/Java/whatever...You make a good argument for that case. However, I decided against the C++ notion of 'best fit' because the combination of all the best fit rules is very confusing. There are 3 levels of matching in D (rather than an arbitrarilly large number with several special case rules tossed in) which are 1) exact match 2) match with implicit conversions and 3) no match. Sure, in D, you'll have a cast or two extra once in a while, but the payoff is a clear set of simple rules, rather than a morass of confusing, subtle ones. I will also argue that a function with int and double overloads that gets passed a character literal perhaps is not designed right, though I could be wrong as I don't know the details of your specific application.
Apr 02 2004
"Walter" <walter digitalmars.com> wrote in message news:c4jafo$96k$1 digitaldaemon.com..."Derek Parnell" <Derek.Parnell psyc.ward> wrote in message news:opr5tcocfiu2m3b2 news.digitalmars.com...FooWalter, as I understand it, I can get this message "constructor this overloadshave(int x) and Foo (double x) both match argument list for this" when Imoredefined ... this(int x) { ... } this(double x) { ... } and I then try to do this ... Foo a = new Foo('D'); Which means that the compiler has decided that the literal character 'D' could be either an integer or a double and therefore the coder must make the call explicit. So my question is - how often have you even seen a coder write a literal character down to mean a double (floating point) value? I would have thought that the overwhelming practice is that a literal character represents an integer and if a coder really needs it to be a double they would explicitly cast it as such... double x = cast(double)'D'; With the current D implementation, the coder nearly always has to doSure,work now than they used to do (for the same idiom) in C/C++/Java/whatever...You make a good argument for that case. However, I decided against the C++ notion of 'best fit' because the combination of all the best fit rules is very confusing. There are 3 levels of matching in D (rather than an arbitrarilly large number with several special case rules tossed in) which are 1) exact match 2) match with implicit conversions and 3) no match.in D, you'll have a cast or two extra once in a while, but the payoff is a clear set of simple rules, rather than a morass of confusing, subtle ones.Thanks. However I'm not actually talking about the rules for matching function signatures. All I'm trying to say is that a character literal is an integer and is never a floating point value. Okay, let's have a straw poll - hands up all the people who have coded a character literal in order to represent a floating point value. Hmmmm...okay then. Hands up all the people who have ever been confused or uncertain about whether a character literal is an interger or floating point value. Walter, I'm not talking about Foo(int) and Foo(double)... I'm just saying that every coder that I've ever talked with, just assumes that a character literal represents an integer value and never represents a floating point value.I will also argue that a function with int and double overloads that gets passed a character literal perhaps is not designed right, though I couldbewrong as I don't know the details of your specific application.And because you could be wrong, is the main reason to allow the CODER to decide if it worthwhile or not, not the language designer. But back to your discussion about matching int and double. Because I can't have ... this(int x){...} AND this(double x){...} I've had to resort to this workaround... this(double x) { if ( (cast(int)x) == x) { < ...do integer processing...> } else { <... do floating point processing...> } } Just so I could write in the application ... Foo a = new Foo('D'); Crazy, eh?! So if you could see your way to making the (alredy assumed by thousands of coders) rule that a character literal represents an 'int' then you have made coding in D just a little bit simplier. And in terms of consistancy, if the ctor's above refuse to handle character literals, why does this work ... int x = 'a'; To be consistant, the D compiler would also have to say that because 'a' might be either an integer OR a double, it can't blindly go implictly converting the 'a' to an integer. That's what its doing for the ctor case! Either that or start allowing .... int x = 1.23; because it obviously does know how to convert a floating point into an integer because ... int x = (cast (int)1.23); works just fine as a built-in conversion. -- Derek
Apr 02 2004
Derek Parnell wrote:Thanks. However I'm not actually talking about the rules for matching function signatures. All I'm trying to say is that a character literal is an integer and is never a floating point value. Okay, let's have a straw poll - hands up all the people who have coded a character literal in order to represent a floating point value. Hmmmm...okay then. Hands up all the people who have ever been confused or uncertain about whether a character literal is an interger or floating point value. Walter, I'm not talking about Foo(int) and Foo(double)... I'm just saying that every coder that I've ever talked with, just assumes that a character literal represents an integer value and never represents a floating point value.Actually I assume that a character literal represents a byte.And because you could be wrong, is the main reason to allow the CODER to decide if it worthwhile or not, not the language designer.But the programmer has the option with casting, its just that in most cases they are probably wrong. All the programmer has to do is explicitly say what they mean.But back to your discussion about matching int and double. Because I can't have ... this(int x){...} AND this(double x){...} I've had to resort to this workaround...Why not?this(double x) { if ( (cast(int)x) == x) { < ...do integer processing...> } else { <... do floating point processing...> } }This only archives loss of information.Just so I could write in the application ... Foo a = new Foo('D');Why not? this(double d) { printf("d\n");} this(int i) { printf("i\n");} this(char c) { this((int)c);}Crazy, eh?! So if you could see your way to making the (alredy assumed by thousands of coders) rule that a character literal represents an 'int' then you have made coding in D just a little bit simplier.In my opinion this makes things more difficult. How often do you need to convert a character to integer? C coders also assume that they need to delete every object they create manually, so what's your point?And in terms of consistancy, if the ctor's above refuse to handle character literals, why does this work ... int x = 'a';Here it's obvious what the programmer means so why write the word (int) twice in the same sentence. With overloading, its often much more difficult to determine what the programmer means because the definition part of the code is somewhere else.To be consistant, the D compiler would also have to say that because 'a' might be either an integer OR a double, it can't blindly go implictly converting the 'a' to an integer. That's what its doing for the ctor case! Either that or start allowing .... int x = 1.23; because it obviously does know how to convert a floating point into an integer because ... int x = (cast (int)1.23); works just fine as a built-in conversion.And so it should behave this way. "int x = 1.23" is obviously a programming error. IMHO the language should try to help out the programmer (where possible) by making obvious semantic errors, syntactical ones. -- -Anderson: http://badmama.com.au/~anderson/
Apr 02 2004
"J Anderson" <REMOVEanderson badmama.com.au> wrote in message news:c4k13a$1dps$1 digitaldaemon.com...Derek Parnell wrote:anThanks. However I'm not actually talking about the rules for matching function signatures. All I'm trying to say is that a character literal isorderinteger and is never a floating point value. Okay, let's have a straw poll - hands up all the people who have coded a character literal intheto represent a floating point value. Hmmmm...okay then. Hands up allcharacterpeople who have ever been confused or uncertain about whether a character literal is an interger or floating point value. Walter, I'm not talking about Foo(int) and Foo(double)... I'm just saying that every coder that I've ever talked with, just assumes that aAnd is a byte an integer or a floating point value? I think its an integer. I never think that a byte is a floating point value. Notice that I'm NOT talking about data storage formats such as 'int' and 'double' (yet), but 'integer' and 'floating point' VALUES.literal represents an integer value and never represents a floating point value.Actually I assume that a character literal represents a byte.But with character literals we DO NOT have the option of casting - we are forced to cast it to the obvious 'int'. Foo x = new Foo('a'); // FAILS Foo y = new Foo(cast(int)'a'); // Works. But when is the 'a' ever a floating point value? It is always an integer value. Therefore, IMNSHO, D should implictly convert it to an int and not even bother trying to convert it a double.And because you could be wrong, is the main reason to allow the CODER to decide if it worthwhile or not, not the language designer.But the programmer has the option with casting, its just that in most cases they are probably wrong. All the programmer has to do is explicitly say what they mean.can'tBut back to your discussion about matching int and double. Because IBecause the D complier spits out an error message. And I quote "constructor this overloads Foo (int a) and Foo (double a) both match argument list for this"have ... this(int x){...} AND this(double x){...} I've had to resort to this workaround...Why not?What?! How could you possibly know what the difference between the "integer processing" and "floating point processing" is, to say that information is being lost? I honestly do not understand your remark.this(double x) { if ( (cast(int)x) == x) { < ...do integer processing...> } else { <... do floating point processing...> } }This only archives loss of information.Thank you very very much. This is the answer to my fuzzy thinking. You have made it clear to me at last. I had just assumed that D thought that a character literal was an 'int' when (of course I see now) it is a 'char'. Now I can sleep tonight ;-)Just so I could write in the application ... Foo a = new Foo('D');Why not? this(double d) { printf("d\n");} this(int i) { printf("i\n");} this(char c) { this((int)c);}thenCrazy, eh?! So if you could see your way to making the (alredy assumed by thousands of coders) rule that a character literal represents an 'int'I forgot that a 'char' is a different beast to an 'int'. I'm back on the righteous path now ;-)you have made coding in D just a little bit simplier.In my opinion this makes things more difficult. How often do you need to convert a character to integer?C coders also assume that they need to delete every object they create manually, so what's your point?I'm still a newbie with heaps of baggage to unlearn. Thanks for helping me. -- Derek
Apr 02 2004
Derek Parnell wrote:And is a byte an integer or a floating point value? I think its an integer. I never think that a byte is a floating point value. Notice that I'm NOT talking about data storage formats such as 'int' and 'double' (yet), but 'integer' and 'floating point' VALUES.Right-oBut with character literals we DO NOT have the option of casting - we are forced to cast it to the obvious 'int'. Foo x = new Foo('a'); // FAILS Foo y = new Foo(cast(int)'a'); // Works. But when is the 'a' ever a floating point value? It is always an integer value. Therefore, IMNSHO, D should implictly convert it to an int and not even bother trying to convert it a double.a is a character.Because the D complier spits out an error message. And I quote "constructor this overloads Foo (int a) and Foo (double a) both match argument list for this"Humm, your right, wrong error message. Obviously the compiler is converting character to an integer before running that test. I think you shouldn't be allowed to actually pass a character into a function that is meant to do integer stuff, you most-probably meant that character for something else. If you do need it, it, should be cast.Sorry I was thinking 64-bit integers (dam C++).What?! How could you possibly know what the difference between the "integer processing" and "floating point processing" is, to say that information is being lost? I honestly do not understand your remark.this(double x) { if ( (cast(int)x) == x) { < ...do integer processing...> } else { <... do floating point processing...> } }This only archives loss of information.I'm happy to hear that. -- -Anderson: http://badmama.com.au/~anderson/Why not? this(double d) { printf("d\n");} this(int i) { printf("i\n");} this(char c) { this((int)c);}Thank you very very much. This is the answer to my fuzzy thinking. You have made it clear to me at last. I had just assumed that D thought that a character literal was an 'int' when (of course I see now) it is a 'char'. Now I can sleep tonight ;-) I forgot that a 'char' is a different beast to an 'int'. I'm back on the righteous path now ;-)
Apr 02 2004
"Derek Parnell" <not available.com> wrote in message news:c4jvgu$1a8s$1 digitaldaemon.com...Walter, I'm not talking about Foo(int) and Foo(double)... I'm just saying that every coder that I've ever talked with, just assumes that a character literal represents an integer value and never represents a floating point value.The underlying thing going on here is that the C integral promotion rules will promote a char value to a floating point value. Changing those rules is tempting, but will cause too many subtle behavior differences from C/C++. I tried to avoid subtle behavior differences, especially in the arena of things like promotion rules, because it can be really hard to notice them in complex expressions which abound in C/C++. Tripping an explicit error in D is preferable because it's at least obvious that there's something that needs adjusting.getsI will also argue that a function with int and double overloads thatD aims to make what is generally considered to be good programming practice easier to write, while making what is generally considered to be bad practice harder to write (so it stands out). A poorly designed language makes good code hard to write and bad code easy to write.passed a character literal perhaps is not designed right, though I couldbewrong as I don't know the details of your specific application.And because you could be wrong, is the main reason to allow the CODER to decide if it worthwhile or not, not the language designer.But back to your discussion about matching int and double. Because I can't have ... this(int x){...} AND this(double x){...}You can have it by adding: this(char c) { ... }Crazy, eh?! So if you could see your way to making the (alredy assumed by thousands of coders) rule that a character literal represents an 'int'thenyou have made coding in D just a little bit simplier.Buried in C is also the rule that chars get implicitly promoted to floating point values.And in terms of consistancy, if the ctor's above refuse to handlecharacterliterals, why does this work ... int x = 'a'; To be consistant, the D compiler would also have to say that because 'a' might be either an integer OR a double, it can't blindly go implictly converting the 'a' to an integer. That's what its doing for the ctor case!In the initialization case, there is no ambiguity, so there is no special case rule the language is applying. The following also works in C and D: double d = 'a';
Apr 02 2004
Thank you Walter. You have given excellent answers here. I can understand your point of view and rationale for D's behaviour. Who knows, maybe someday I might even come around to sharing this POV too ;-) "Walter" <walter digitalmars.com> wrote in message news:c4k5jp$1mpv$1 digitaldaemon.com..."Derek Parnell" <not available.com> wrote in message news:c4jvgu$1a8s$1 digitaldaemon.com...sayingWalter, I'm not talking about Foo(int) and Foo(double)... I'm justcharacterthat every coder that I've ever talked with, just assumes that apointliteral represents an integer value and never represents a floatingisvalue.The underlying thing going on here is that the C integral promotion rules will promote a char value to a floating point value. Changing those rulestempting, but will cause too many subtle behavior differences from C/C++.Itried to avoid subtle behavior differences, especially in the arena of things like promotion rules, because it can be really hard to notice themincomplex expressions which abound in C/C++. Tripping an explicit error in D is preferable because it's at least obvious that there's something that needs adjusting.couldgetsI will also argue that a function with int and double overloads thatpassed a character literal perhaps is not designed right, though IpracticebeD aims to make what is generally considered to be good programmingwrong as I don't know the details of your specific application.And because you could be wrong, is the main reason to allow the CODER to decide if it worthwhile or not, not the language designer.easier to write, while making what is generally considered to be bad practice harder to write (so it stands out). A poorly designed language makes good code hard to write and bad code easy to write.can'tBut back to your discussion about matching int and double. Because Ibyhave ... this(int x){...} AND this(double x){...}You can have it by adding: this(char c) { ... }Crazy, eh?! So if you could see your way to making the (alredy assumedfloatingthousands of coders) rule that a character literal represents an 'int'thenyou have made coding in D just a little bit simplier.Buried in C is also the rule that chars get implicitly promoted topoint values.case!And in terms of consistancy, if the ctor's above refuse to handlecharacterliterals, why does this work ... int x = 'a'; To be consistant, the D compiler would also have to say that because 'a' might be either an integer OR a double, it can't blindly go implictly converting the 'a' to an integer. That's what its doing for the ctorIn the initialization case, there is no ambiguity, so there is no special case rule the language is applying. The following also works in C and D: double d = 'a';
Apr 02 2004
"Derek Parnell" <not available.com> wrote in message news:c4kpcn$2k7h$1 digitaldaemon.com...Thank you Walter. You have given excellent answers here. I can understand your point of view and rationale for D's behaviour. Who knows, maybesomedayI might even come around to sharing this POV too ;-)It's unreasonable to expect everyone to agree with me on every point, but I am glad I was able to explain the rationale in a lucid manner.
Apr 02 2004
You make a good argument for that case. However, I decided against the C++ notion of 'best fit' because the combination of all the best fit rules is very confusing. There are 3 levels of matching in D (rather than an arbitrarilly large number with several special case rules tossed in) which are 1) exact match 2) match with implicit conversions and 3) no match. Sure, in D, you'll have a cast or two extra once in a while, but the payoff is a clear set of simple rules, rather than a morass of confusing, subtle ones.I proved that dmd doesn't follow this rule (haven't tested with the current version. I did it with 0.7x, can't remember the exact version). So have you fixed it? I didn't want you to do so. Damn. (The thread was called "A bug that I like", if I remember right)
Apr 04 2004
"Matthias Becker" <Matthias_member pathlink.com> wrote in message news:c4oftn$2200$1 digitaldaemon.com...I proved that dmd doesn't follow this rule (haven't tested with thecurrentversion. I did it with 0.7x, can't remember the exact version). So haveyoufixed it? I didn't want you to do so. Damn. (The thread was called "A bug that I like", if I remember right)I don't remember that particular problem. If it is in the bug database, however, it will remain there until it gets fixed.
Apr 04 2004
Matthias Becker wrote:I don't know that Walter changed anything. Perhaps he already fixed the bug before he found saw your post. I think I found your earlier post (http://www.digitalmars.com/drn-bin/wwwnews?D/24040) and Walter's reply (http://www.digitalmars.com/drn-bin/wwwnews?D/24465). I got the same error message that Walter seemed to get: fn_ovrld.d(17): function func overloads void(Foo foo) and void(Bar bar) both match argument list for func I tested it with DMD 0.81. (I guess it's time for me install DMD 0.82.) -- Justin http://jcc_7.tripod.com/d/You make a good argument for that case. However, I decided against the C++ notion of 'best fit' because the combination of all the best fit rules is very confusing. There are 3 levels of matching in D (rather than an arbitrarilly large number with several special case rules tossed in) which are 1) exact match 2) match with implicit conversions and 3) no match. Sure, in D, you'll have a cast or two extra once in a while, but the payoff is a clear set of simple rules, rather than a morass of confusing, subtle ones.I proved that dmd doesn't follow this rule (haven't tested with the current version. I did it with 0.7x, can't remember the exact version). So have you fixed it? I didn't want you to do so. Damn. (The thread was called "A bug that I like", if I remember right)
Apr 04 2004