Re: abs and minimum values
On Thursday, 28 October 2021 at 21:23:15 UTC, kyle wrote: ``` void main() { import std.math : abs, sgn; alias n_type = short; //or int, long, byte, whatever assert(n_type.min == abs(n_type.min)); assert(sgn(abs(n_type.min)) == -1); } ``` I stumbled into this fun today. I understand why abs yields a negative value here with overflow and no promotion. I just want to know if it should. Should abs ever return a negative number? Thanks. I think that the best way to deal with this stuff without losing sanity is to introduce a special constant "n_type.nan" for signed integer data types. Then you get "abs(n_type.nan) == n_type.nan", which makes more sense. All the uses of "n_type.min" in your code can be replaced either with "n_type.nan" or "-n_type.max", depending on the context and your intention. The existing constant "n_type.min" can be deprecated for signed integer types. Compilers and static analysis tools could warn about its use.
Re: abs and minimum values
On Friday, 29 October 2021 at 08:05:35 UTC, Dom DiSc wrote: On Thursday, 28 October 2021 at 21:26:04 UTC, kyle wrote: Okay I checked the phobos docs and it does say "Limitations Does not work correctly for signed intergal types and value Num.min." Should have looked there first, I know. Still seems pretty silly. I recommend to implement your own abs function this way (was not accepted for phobos, as it now does NOT return the same type as the argument, which was considered a "breaking change" :-( ): ```D /// get the absolute value of x as unsigned type. always succeeds, even for T.min Unsigned!T abs(T)(const(T) x) if(isIntegral!T) { static if(isSigned!T) if(x < 0) return cast(Unsigned!T)-x; return x; } ``` Just fix it for floats and it would be all round 100 times better than what we currently have ☀
Re: Does associative array change the location of values?
On Sat, Oct 30, 2021 at 07:56:35PM -0700, Ali Çehreli via Digitalmars-d-learn wrote: > On 10/30/21 3:47 PM, Elronnd wrote: > > > If the GC were moving, it would also have to move the pointers you > > took to AA elements. > > I doubt D's GC can ever change pointer values because the values may > be hiding inside e.g. ulong variables. And we would definitely not > want the GC to change ulong values just because it thought they were > familiar pointer values in disguise. :) [...] The current spec explicitly states that masking pointers this way is UB. T -- Без труда не выловишь и рыбку из пруда.
Re: abs and minimum values
On Sunday, 31 October 2021 at 10:12:49 UTC, Siarhei Siamashka wrote: On Sunday, 31 October 2021 at 05:04:33 UTC, Dom DiSc wrote: On Friday, 29 October 2021 at 14:20:09 UTC, Ali Çehreli wrote: [...] This should be no surprise. You need to know what the resulting type of int + uint should be. And it is .. uint! which is one of the stupit integer-promotion rules inherited from C. Then let's change the example to: int b = -4; writeln(-abs(b)); What would one normally expect to be printed here? Should the unary minus operator also do some kind of implicit "unsigned -> signed" type change magic to accommodate this modified version of the abs function and make it behave in a non-surprising way? What I would like is for it to mirror math.
The type inference everywhere
```d auto foo(int value, auto s = Section(2, 60)) { int max; /* ^--- ? ...*/ return Section (0, max) } ``` Is possible something like above pointed. OK, I know it isn't because I tried! Well, wouldn't it be nice if it did? Why shouldn't the inference be possible on default argument? Peek out of rvalue... Thanks...
Re: abs and minimum values
On Sunday, 31 October 2021 at 05:04:33 UTC, Dom DiSc wrote: On Friday, 29 October 2021 at 14:20:09 UTC, Ali Çehreli wrote: Unsigned!T abs(T)(const(T) x) if(isIntegral!T) { static if(isSigned!T) if(x < 0) return cast(Unsigned!T)-x; return x; } void main() { int a = -5; int b = -4; writeln(a + abs(b)); // -5 + 4 == -1? (No!) } The program prints uint.max. This should be no surprise. You need to know what the resulting type of int + uint should be. And it is .. uint! which is one of the stupit integer-promotion rules inherited from C. Then let's change the example to: int b = -4; writeln(-abs(b)); What would one normally expect to be printed here? Should the unary minus operator also do some kind of implicit "unsigned -> signed" type change magic to accommodate this modified version of the abs function and make it behave in a non-surprising way?
Re: Does associative array change the location of values?
On 10/31/21 9:49 AM, H. S. Teoh wrote: > The current spec explicitly states that masking pointers this way is UB. Ok. :) What about unions? union U { ulong u; void* p; } Can the GC deal with that? Or other smart ways where I store the pointer in two parts as page+offset? (Perhaps that's UB as well.) Ali
srand in D
Hi! I'm C learner and found the high similarity between C and D, and was converting C code into D but couldn't get the equivalent of this C statement "srand(time(NULL));".
Re: abs and minimum values
On 10/30/21 10:04 PM, Dom DiSc wrote: > On Friday, 29 October 2021 at 14:20:09 UTC, Ali Çehreli wrote: >> Unsigned!T abs(T)(const(T) x) if(isIntegral!T) >> { >>static if(isSigned!T) if(x < 0) return cast(Unsigned!T)-x; >>return x; >> } >> >> void main() { >> int a = -5; >> int b = -4; >> writeln(a + abs(b)); // -5 + 4 == -1? (No!) >> } >> >> The program prints uint.max. > > This should be no surprise. You need to know what the resulting type of > int + uint should be. Yes, the programmer knew all that when they wrote that code when abs() behaved the way it behaves today. The code is an example of why abs() cannot be changed today to what you propose. It would be a bad kind of breaking change: No compilation error, no run-time error (if unlucky), and a weird bug 42 months from today. Ali
Re: abs and minimum values
On Sunday, 31 October 2021 at 05:04:33 UTC, Dom DiSc wrote: This should be no surprise. You need to know what the resulting type of int + uint should be. And it is .. uint! which is one of the stupit integer-promotion rules inherited from C. In C++ it is undefined behaviour to take the absolute value of a value that has no positive representation. I assume the same is true for C? So you can write a compiler that detects it and fails. You cannot do this in D as int is defined to represent an infinite set of numbers (mapped as a circle). So in D, you could say that the abs of the most negative value is a positive value that is represented as a negative due to circular wrapping. If this happens in C then it is a bug. If it happens in D, then it is a defined feature of the language.
Re: abs and minimum values
On Sunday, 31 October 2021 at 10:32:50 UTC, Imperatorn wrote: What I would like is for it to mirror math. Use bigints.
Re: srand in D
On Sunday, 31 October 2021 at 17:02:00 UTC, Ali Çehreli wrote: On 10/31/21 9:54 AM, pascal111 wrote: Hi! I'm C learner and found the high similarity between C and D, and was converting C code into D Welcome! :) In case it makes to your use cases, check out -betterC as well: https://dlang.org/spec/betterc.html > but couldn't get the equivalent of this C statement "srand(time(NULL));". Just comment that line out. :) D's pseudo-random generators start randomized by default: import std.stdio; import std.random; void main() { // Pick a number between [0,10) writeln(uniform(0, 10)); } The documentation is at https://dlang.org/phobos/std_random.html Ali Thanks! the code works now: /* Acey Ducey game, originally programmed in BASIC */ // D programming language import std.stdio; import core.stdc.stdlib; import std.ascii; import core.stdc.string; import core.stdc.stdio; import core.time; import std.conv; import std.random; /* char* card_name(int); // turning cards valuse into strings function void no_money_test(ref int); // money = 0 test */ // turning cards valuse into strings function void card_name(int x, ref string c) { /* char* c=cast(char*) malloc((strlen("queen")+1)*(char.sizeof)); if(!c){ writeln("A memory allocation failed!"); exit(EXIT_FAILURE);} */ switch (x) { case 11: c="Jack"; break; case 12: c="Queen"; break; case 13: c="King"; break; case 14: c="Ace"; break; default: c=to!string(x); } } // money = 0 test void no_money_test(ref int your_money) { char q; if (your_money == 0) { do { writeln("Oops! you have no money to bet with,"); write("do you want playing again (y/n)? "); readf(" %c", ); } while ((toLower(q)!='y') && (toLower(q)!='n')); if (toLower(q)=='y') // nasted in 'if money = 0' { your_money = 100; } else exit(EXIT_SUCCESS); } // if money = 0 } int main() { int your_money=100; int card_A, card_B, card_C; string card_A_name, card_B_name, card_C_name; char q; int bet_much; //srand(time(NULL)); do // 1st do { writeln("You've ", your_money, "$"); // Generating the two cards: do { card_A = uniform(0, 13)+2; //(rand()%13)+2; card_B = uniform(0, 13)+2; } while (!((card_B - card_A) > 2) && !((card_A==2)&&(card_B==14))); card_name(card_A, card_A_name); card_name(card_B, card_B_name); writeln("Here are your two cards: ", card_A_name, " ", card_B_name); // Betting query: card_C = uniform(0, 13)+2; do { write("Do you'll bet (y/n/e = (exit))? "); readf(" %c", ); } while ((toLower(q)!='y') && (toLower(q)!='n') && (toLower(q)!='e')); // agreeing betting if (toLower(q)=='y') { do { write("With how much? "); readf(" %d", _much); if (bet_much>your_money) { writeln("You don't have this much to bet with,"); writeln("you have ", your_money, "$"); } } while (!(bet_much<=your_money)); if ((card_C>=card_A) && (card_C<=card_B)) // following agreeing betting 'if' { card_name(card_C, card_C_name); writeln("You are right! "); writeln("3rd card is: ", card_C_name); your_money+=bet_much; } else { card_name(card_C, card_C_name); writeln("Oops! you are wrong!"); writeln("3rd card is: ", card_C_name); your_money-=bet_much; } } else // 'else if' of agreeing betting 'if' if(toLower(q)=='e') exit(0); else // considered final 'else' of agreeing betting 'if' writeln("CHICKEN!!!"); // Your money = 0 test no_money_test(your_money); } while (true); // 1st do return 0; } // C version of the same game /* Acey Ducey game, originally programmed in BASIC */ #include #include #include #include #include #include using namespace std; char *card_name(int); // turning cards valuse into strings function void no_money_test(int&); // money = 0 test int main(void) { int your_money=100; int card_A, card_B, card_C; char q; int bet_much; srand(time(NULL)); do // 1st do { cout << "You've " << your_money << "$" << endl; // Generating the two cards: do { card_A = (rand()%13)+2; card_B = (rand()%13)+2; } while (!((card_B - card_A) > 2) && !((card_A==2)&&(card_B==14))); cout << "Here are your two cards: " << card_name(card_A) << " " << card_name(card_B) << endl; // Betting query: card_C = (rand()%13)+2; do { cout << "Do you'll bet (y/n/e = (exit))? "; cin >> q; } while ((tolower(q)!='y') && (tolower(q)!='n') && (tolower(q)!='e')); // agreeing betting if (tolower(q)=='y') { do { cout << "With how much? "; cin >> bet_much; if (bet_much>your_money) { cout << "You don't have this much to bet with," << endl << "you have " << your_money << "$" << endl; } } while (!(bet_much<=your_money)); if ((card_C>=card_A) &&
Re: The type inference everywhere
On Sunday, 31 October 2021 at 18:51:09 UTC, user1234 wrote: To me it is the right answer. Maybe that OP wanted the TemplateType parameter to be implicitly added (and that's why Ali interpreted the question as a language proposal)? Ah, I see. Interesting proposal.
Re: srand in D
On 10/31/21 9:54 AM, pascal111 wrote: Hi! I'm C learner and found the high similarity between C and D, and was converting C code into D Welcome! :) In case it makes to your use cases, check out -betterC as well: https://dlang.org/spec/betterc.html > but couldn't get the equivalent of this C statement "srand(time(NULL));". Just comment that line out. :) D's pseudo-random generators start randomized by default: import std.stdio; import std.random; void main() { // Pick a number between [0,10) writeln(uniform(0, 10)); } The documentation is at https://dlang.org/phobos/std_random.html Ali
Re: Does associative array change the location of values?
On Sun, Oct 31, 2021 at 09:54:23AM -0700, Ali Çehreli via Digitalmars-d-learn wrote: > On 10/31/21 9:49 AM, H. S. Teoh wrote: > > > The current spec explicitly states that masking pointers this way is UB. > > Ok. :) What about unions? > > union U { > ulong u; > void* p; > } > > Can the GC deal with that? https://dlang.org/spec/garbage.html#obj_pinning_and_gc Though I have to say, object pinning does impose restrictions on a moving GC implementation that may negate some of its benefits. T -- Never criticize a man until you've walked a mile in his shoes. Then when you do criticize him, you'll be a mile away and he won't have his shoes.
Re: The type inference everywhere
On 10/31/21 7:07 AM, Salih Dincer wrote: > ```d > auto foo(int value, auto s = Section(2, 60)) { > int max; /* ^--- ? > ...*/ > return Section (0, max) > } > ``` > Is possible something like above pointed. OK, I know it isn't because I > tried! Well, wouldn't it be nice if it did? Makes sense because e.g. the following works: struct S { auto i = 42; } I bet the problem with your proposal is "auto" in that position is a part of the two-word "auto ref" parameters. I don't know how hard or impossible it would be to allow just "auto" there. In any case, although it would be nice for completeness, the use case is so rare that I wouldn't mind repeating the type twice in that usage. But I agree with you... Ali
Re: The type inference everywhere
On Sunday, 31 October 2021 at 17:35:35 UTC, Ali Çehreli wrote: On 10/31/21 7:07 AM, Salih Dincer wrote: > ```d > auto foo(int value, auto s = Section(2, 60)) { > int max; /* ^--- ? > ...*/ > return Section (0, max) > } > ``` > Is possible something like above pointed. OK, I know it isn't because I > tried! Well, wouldn't it be nice if it did? Makes sense because e.g. the following works: struct S { auto i = 42; } I bet the problem with your proposal is "auto" in that position is a part of the two-word "auto ref" parameters. I don't know how hard or impossible it would be to allow just "auto" there. In any case, although it would be nice for completeness, the use case is so rare that I wouldn't mind repeating the type twice in that usage. But I agree with you... Ali This is a teachable moment for me, so I'll ask the question. Why isn't something like this the answer? ``` import std.stdio: writeln; struct Section { int x; int y; } auto foo(T)(int value, auto ref T s = Section(2, 60)) { //... return Section(0, 60); } void main() { foo(5).writeln; } ```
Re: Does associative array change the location of values?
On 10/31/21 9:54 AM, Ali Çehreli wrote: Or other smart ways where I store the pointer in two parts as page+offset? Ok, that was silly. There would be no reference to the GC memory if I chopped off a pointer. :/ Ali
Re: srand in D
On Sunday, 31 October 2021 at 16:54:35 UTC, pascal111 wrote: Hi! I'm C learner and found the high similarity between C and D, and was converting C code into D but couldn't get the equivalent of this C statement "srand(time(NULL));". Since D gives you access to the C standard library, you can use pretty much exactly the same code in D: ```d import core.stdc.stdlib; // bindings for import core.stdc.time; // bindings for srand(time(null)); // null is lower-case in D ``` If you want to use D's standard library, you can instead use [`std.random.rndGen`][1], the default random number generator. Its documentation says: It is allocated per-thread and initialized to an unpredictable value for each thread. In other words, it is seeded for you automatically. So when you are converting C code that uses `rand` to D code that uses `rndGen`, you can simply delete the line `srand(time(NULL));`, and it will work ask expected. If you wanted to seed it yourself, however, you would do it using the `.seed` method, and generate the seed using [`std.random.unpredictableSeed`][2]. ```d import std.random; rndGen.seed(unpredictableSeed()); ``` This is mainly useful when you are using a custom RNG instead of the default `rndGen`, since custom RNGs are *not* automatically seeded. [1]: https://phobos.dpldocs.info/std.random.rndGen.html [2]: https://phobos.dpldocs.info/std.random.unpredictableSeed.1.html
Re: The type inference everywhere
On Sunday, 31 October 2021 at 17:51:45 UTC, data pulverizer wrote: On Sunday, 31 October 2021 at 17:35:35 UTC, Ali Çehreli wrote: On 10/31/21 7:07 AM, Salih Dincer wrote: > [...] because I > [...] Makes sense because e.g. the following works: struct S { auto i = 42; } I bet the problem with your proposal is "auto" in that position is a part of the two-word "auto ref" parameters. I don't know how hard or impossible it would be to allow just "auto" there. In any case, although it would be nice for completeness, the use case is so rare that I wouldn't mind repeating the type twice in that usage. But I agree with you... Ali This is a teachable moment for me, so I'll ask the question. Why isn't something like this the answer? ``` import std.stdio: writeln; struct Section { int x; int y; } auto foo(T)(int value, auto ref T s = Section(2, 60)) { //... return Section(0, 60); } void main() { foo(5).writeln; } ``` To me it is the right answer. Maybe that OP wanted the TemplateType parameter to be implicitly added (and that's why Ali interpreted the question as a language proposal)?
Re: The type inference everywhere
On Sunday, 31 October 2021 at 17:35:35 UTC, Ali Çehreli wrote: On 10/31/21 7:07 AM, Salih Dincer wrote: > ```d > auto foo(int value, auto s = Section(2, 60)) { > int max; /* ^--- ? > ...*/ > return Section (0, max) > } > ``` > Is possible something like above pointed. OK, I know it isn't because I > tried! Well, wouldn't it be nice if it did? Makes sense because e.g. the following works: struct S { auto i = 42; } I bet the problem with your proposal is "auto" in that position is a part of the two-word "auto ref" parameters. I don't know how hard or impossible it would be to allow just "auto" there. In any case, although it would be nice for completeness, the use case is so rare that I wouldn't mind repeating the type twice in that usage. But I agree with you... Ali Actually, foo is inside a class. So using T is very easy. Moreover,it's possible to do it with ```alias S = Section;```