digitalmars.D.learn - Question about iteger literals
- Uranuz (34/34) Jun 22 2014 I have the following programme
- bearophile (29/37) Jun 22 2014 Better to use this signature (assuming you want a ushort result,
- Uranuz (4/7) Jun 22 2014 I understand what pure, nothrow and @safe mean there. But what
- Uranuz (8/8) Jun 22 2014 In expression
- bearophile (8/13) Jun 22 2014 In D operations among chars return a int. The same happens in
- Uranuz (1/6) Jun 22 2014 Ok. Thank you! I never thought about it that way
- Uranuz (3/3) Jun 22 2014 Another stupid question. Using this logic substraction for two
- bearophile (9/12) Jun 22 2014 There are no stupid questions, there are only some stupid answers.
- Uranuz (24/27) Jun 22 2014 Now this code
- bearophile (15/17) Jun 22 2014 Despite D being only 14 years old, one of its rules is to
- Uranuz (13/13) Jun 22 2014 If these rules are not so clear and have some exceptions (but I
- Steven Schveighoffer (5/8) Jun 23 2014 See integer promotion rules:
- Uranuz (18/27) Jul 20 2014 I see these rules but when I compile following code and it fails
- Uranuz (2/18) Jul 20 2014 I just should forget about all integer type except *int*, because
- bearophile (6/11) Jul 20 2014 In C/C++/D if you sum a types that are smaller than int, you
- Uranuz (21/26) Jul 20 2014 Is there any reasoning why this should remain unchainged? How
- bearophile (7/8) Jun 22 2014 @nogc will be present in dmd 2.066, it means that the function
I have the following programme import std.stdio; bool isDigit(char c) nothrow { return c >= '0' && c <= '9'; } ushort hexValue(char c) nothrow { if( isDigit(c) ) return c - '0'; else if (c >= 'a' && c <= 'f') return c - 'a' + 10; else if (c >= 'A' && c <= 'F') return c - 'A' + 10; else return ushort.max; } void main() { writeln(hexValue('A')); } This example is compiling successfully in DMD 2.064 but in DMD 2.065 a got the following error: /d544/f547.d(12): Error: cannot implicitly convert expression (cast(int)c - 48) of type int to ushort /d544/f547.d(14): Error: cannot implicitly convert expression (cast(int)c - 97 + 10) of type int to ushort /d544/f547.d(16): Error: cannot implicitly convert expression (cast(int)c - 65 + 10) of type int to ushort So I have a question why these expressions are casted to int? I was thinking that result should be of char type. And it could be implicitly converted to ushort (because there is enough place to store result). Is it a bug in compiler or I should insert explicit casts?
Jun 22 2014
Uranuz:bool isDigit(char c) nothrowThis function is already in Phobos, it's std.ascii.isDigit.ushort hexValue(char c) nothrowBetter to use this signature (assuming you want a ushort result, despite a ubyte suffices and a uint is faster): ushort hexValue(in char c) pure nothrow safe nogcelse return ushort.max;Special error values are not very safe. Consider the usage of a Nullable!(ubyte, ubyte.max) instead, if you can stand the little abstraction penalty.why these expressions are casted to int?Because in C/C++/D if you perform arithmetic operations among types shorter than int you produce an int.I was thinking that result should be of char type.In general it can't be a char.And it could be implicitly converted to ushort (because there is enough place to store result).The precedent compiler version was wrong, and the bug has being fixed by the great Kenji. If you have an expression like: char - 'a' + 10 It means: [0, 255] - 87 That is [-87, 168] that can't fit in the [0, 65535] range. Currently in D the range value analysis works only on the current expression, so the information from the "if(c >= 'a' && c <= 'f')" condition is ignored here. There are discussions and even code to fix this: http://forum.dlang.org/thread/lnrc8l$1254$1 digitalmars.com https://github.com/lionello/dmd/compare/if-else-range https://github.com/D-Programming-Language/dmd/pull/3679 But both Walter and Andrei have so far ignored this significant D improvement, so I don't know if and when it will be added. Bye, bearophile
Jun 22 2014
ushort hexValue(in char c) pure nothrow safe nogcI understand what pure, nothrow and safe mean there. But what nogc changes in there so I should use this modifier? Is it logical specifier that this function can be used without garbage collector or what?else return ushort.max;
Jun 22 2014
In expression return c - 'a' + 10; I could think that 10 has type int and resulting value promoted to the largest type. But I don't understand why in expression where both of arguments have type char: return c - '0'; I have resulting type int. It's very strange for me and looks very buggy)
Jun 22 2014
Uranuz:But I don't understand why in expression where both of arguments have type char: return c - '0'; I have resulting type int. It's very strange for me and looks very buggy)In D operations among chars return a int. The same happens in C/C++. If you subtract a char from a char in general you can have a negative result, that can't fit in a char. So what's buggy is your thinking. Bye, bearophile
Jun 22 2014
In D operations among chars return a int. The same happens in C/C++. If you subtract a char from a char in general you can have a negative result, that can't fit in a char. So what's buggy is your thinking.Ok. Thank you! I never thought about it that way
Jun 22 2014
Another stupid question. Using this logic substraction for two uint values should return int too, because it can produce negative result. Am I right or not?
Jun 22 2014
Uranuz:Another stupid question. Using this logic substraction for two uint values should return int too, because it can produce negative result. Am I right or not?There are no stupid questions, there are only some stupid answers. Generally uint - uint generates a result with a [-4_294_967_295, 4__294_967_295] range, that can't fit in an integer. I think D here makes an exception to its rule, to avoid too many casts. Because too many casts make the code even less safe than breaking the range assignments rules. Bye, bearophile
Jun 22 2014
On Sunday, 22 June 2014 at 11:57:48 UTC, Uranuz wrote:Another stupid question. Using this logic substraction for two uint values should return int too, because it can produce negative result. Am I right or not?Now this code import std.stdio; void main() { uint a = 50; uint b = 60; auto c = a - b; writeln(typeid(c)); } produce output "uint". It's some breakage in my logic. I am thinking that all integer-like types should behave similar way. I perceive char type as ubyte, that should be printed as symbol when using functions like writeln(). But the folowing example import std.stdio; void main() { ubyte a = 50; ubyte b = 60; auto c = a - b; writeln(typeid(c)); } produces output "int" like you said. Why there are so complicated rules in the *new* language. It's hard to understand the logic.
Jun 22 2014
Uranuz:Why there are so complicated rules in the *new* language. It's hard to understand the logic.Despite D being only 14 years old, one of its rules is to (usually) give the same results if you write code that is valid in C. This means it has to follow many rules of C language. If you try your code in C you will see some similar results. This rule of D is quite handy. Other reasons for the current design of D is that sometimes practicality beats design purity, because D is an engineering product. And I guess another reason is that Walter is not a mathematician nor a computer science theorist, so he has not seen some more principled designs, or he has not appreciated them because of their more formal nature. Bye, bearophile
Jun 22 2014
If these rules are not so clear and have some exceptions (but I don't understand why they are needed) then some documentation needed about this. But I would prefer to have result of uint substraction like uint, and char substraction like char. If we will changing all the types it will be kind of mess. Using this logic we should have some bigger type for int multiplication operator to fit in result of multiplication of int.max*int.max. I know that some assembler operations do this and multiplication of two registers with byte size results in placing product into two result register. But in context of higher level programming language it's better to have better type consistensy. Or we will nead a bigger type to store product for ulong.max*ulong.max result. Is it good or not?
Jun 22 2014
On Sun, 22 Jun 2014 08:23:45 -0400, Uranuz <neuranuz gmail.com> wrote:If these rules are not so clear and have some exceptions (but I don't understand why they are needed) then some documentation needed about this.See integer promotion rules: http://dlang.org/type.html#Integer%20Promotions And the section below it. -Steve
Jun 23 2014
On Monday, 23 June 2014 at 18:32:38 UTC, Steven Schveighoffer wrote:On Sun, 22 Jun 2014 08:23:45 -0400, Uranuz <neuranuz gmail.com> wrote:I see these rules but when I compile following code and it fails with error it looks VERY stupid. import std.stdio; void main() { ubyte a = 15; ubyte b = 10; ubyte c = a + b; //What is happening there?! AAAAARGH! Are you joking?! } Compilation output: /d837/f382.d(9): Error: cannot implicitly convert expression (cast(int)a + cast(int)b) of type int to ubyte I'm just crazy about it! How could it happen?!If these rules are not so clear and have some exceptions (but I don't understand why they are needed) then some documentation needed about this.See integer promotion rules: http://dlang.org/type.html#Integer%20Promotions And the section below it. -Steve
Jul 20 2014
I see these rules but when I compile following code and it fails with error it looks VERY stupid. import std.stdio; void main() { ubyte a = 15; ubyte b = 10; ubyte c = a + b; //What is happening there?! AAAAARGH! Are you joking?! } Compilation output: /d837/f382.d(9): Error: cannot implicitly convert expression (cast(int)a + cast(int)b) of type int to ubyte I'm just crazy about it! How could it happen?!I just should forget about all integer type except *int*, because it make my head just explode!!!
Jul 20 2014
Uranuz:ubyte a = 15; ubyte b = 10; ubyte c = a + b; //What is happening there?! AAAAARGH! Are you joking?!In C/C++/D if you sum a types that are smaller than int, you obtain an int. D has copied C for backwards compatibility with C code. Bye, bearophile
Jul 20 2014
In C/C++/D if you sum a types that are smaller than int, you obtain an int. D has copied C for backwards compatibility with C code. Bye, bearophileIs there any reasoning why this should remain unchainged? How could it break interface between languages? And also this code succesfully compiles and runs in C++. #include <iostream> using namespace std; int main() { unsigned short a = 15; unsigned short b = 10; unsigned short c = a + b; //There is no problem cout << c << endl; return 0; } As D compiler doesn't need to compile C programme and have compatible operations with types. Why we still should keep this garbage?! I don't know the right solution but I believe that previous example illustrates some contradiction in integer types system design or implementation. Why we dont promote *ulong* and *long* to int? Let's also promote string into array of ints?! Can't believe it!
Jul 20 2014
Uranuz:But what nogc changes in there so I should use this modifier?nogc will be present in dmd 2.066, it means that the function (and all the functions it calls) can't perform operations that cause a call to GC functions. Sometimes GC operations are a source of performance loss. Bye, bearophile
Jun 22 2014