digitalmars.D.learn - ubyte + ubyte = int
- 0xEAB (25/25) Oct 26 2022 ```d
- =?UTF-8?Q?Ali_=c3=87ehreli?= (10/13) Oct 26 2022 Yes. It is called integer promotions:
- =?UTF-8?Q?Ali_=c3=87ehreli?= (6/7) Oct 26 2022 Reading "Value Range Propagation" further down that link, I learned that...
- Salih Dincer (43/52) Oct 26 2022 You should help the compiler with return type:
- Salih Dincer (27/29) Oct 26 2022 I love D, enjoys it when I code...:)
```d safe: void main() { import std.stdio : writeln; writeln(ubyte(4).toHexDigit); } ubyte toHexDigit(ubyte decimal) pure nothrow nogc { if (decimal < 10) return (decimal + ubyte('0')); if (decimal < 16) return (decimal - ubyte(10) + ubyte('A')); return '\xFF'; } ``` ``` onlineapp.d(12): Error: cannot implicitly convert expression `cast(int)decimal + 48` of type `int` to `ubyte` onlineapp.d(15): Error: cannot implicitly convert expression `cast(int)decimal - 10 + 65` of type `int` to `ubyte` ``` I guess, this fancy behavior is inherited from C. I know this is advanced stuff, but the compiler *could* even prove that the calculation(s) won’t go beyond `ubyte.max`.
Oct 26 2022
On 10/26/22 14:10, 0xEAB wrote:I guess, this fancy behavior is inherited from C.Yes. It is called integer promotions: https://dlang.org/spec/type.html#integer-promotions (The next section is related as well.)I know this is advanced stuff, but the compiler *could* even prove that the calculation(s) won’t go beyond `ubyte.max`.Apparently it does not go that far but there is Value Range Propagation: https://www.digitalmars.com/articles/b62.html That article links to this forum post: https://www.digitalmars.com/d/archives/digitalmars/D/Value_Preservation_and_Polysemy_80224.html#N80293 Ali
Oct 26 2022
On 10/26/22 14:19, Ali Çehreli wrote:https://dlang.org/spec/type.html#integer-promotionsReading "Value Range Propagation" further down that link, I learned that e.g. masking 'decimal' with 0xf makes the code compile: return ((decimal & 0xf) + ubyte('0')); return ((decimal & 0xf) - ubyte(10) + ubyte('A')); Ali
Oct 26 2022
On Wednesday, 26 October 2022 at 21:10:54 UTC, 0xEAB wrote:I know this is advanced stuff, but the compiler *could* even prove that the calculation(s) won’t go beyond `ubyte.max`. ```d //... => char? return (decimal - ubyte(10) + ubyte('A')); return '\xFF'; } ```You should help the compiler with return type: ```d char toHexDigit(ubyte decimal) pure nothrow nogc { if (decimal < 10) return cast(char) (decimal + ubyte('0')); if (decimal < 16) return cast(char) (decimal - ubyte(10) + ubyte('A')); return '\xFF'; } void main() { import std.stdio : writeln; foreach(ubyte n; 0..256) { const c = n.toHexDigit(); if(n < 16) { c.writeln(": ", n); } else assert(c == char.init); } } /* 0: 0 1: 1 2: 2 3: 3 4: 4 5: 5 6: 6 7: 7 8: 8 9: 9 A: 10 B: 11 C: 12 D: 13 E: 14 F: 15 Process finished. */ ``` SDB 79
Oct 26 2022
On Thursday, 27 October 2022 at 01:57:15 UTC, Salih Dincer wrote:You should help the compiler with return type:I love D, enjoys it when I code...:) I played a little on the code, and the following is possible and beautiful: ```d // If you type auto instead of ubyte as return type, the return will be char. ubyte toHexDigit(bool capital = false)(ubyte decimal) { static if(capital) enum start = 'A'; else enum start = 'a'; if(decimal < 10) return cast(char)(decimal + ubyte('0')); if(decimal < 16) return cast(char)(decimal - ubyte(10) + ubyte(start)); return '\xFF'; } unittest { assert(is(typeof(toHexDigit(9)) == ubyte)); assert(toHexDigit(9) == 57); // '9' assert(toHexDigit(10) == 97); // 'a' assert(toHexDigit!true(10) == 65); // 'A' } ``` SDB 79
Oct 26 2022