Re: mod of negative number

2024-09-24 Thread Sergey via Digitalmars-d-learn
On Monday, 23 September 2024 at 19:52:02 UTC, Craig Dillabaugh 
wrote:

Why does the following program:

\
import std.stdio;

int main(string[] args) {
uint Q = 7681;
writeln("Val = ", -1 % Q);
return 0;
}
\

Print
Val = 5568


Was hoping for 1.

I assume it is an integer promotion issue, but I am unsure how 
to resolve.  I tried replacing the Q with to!int(Q) but this 
gave me -1, which is closer but not right either.


Check section "In Programming languages" - 
https://en.wikipedia.org/wiki/Modulo
There are different operations (remainder and modulus) and 
operators (modulo) which could be combined in a different ways


Split by top level comma

2024-09-24 Thread monkyyy via Digitalmars-d-learn
I *strongly* believe the answer is not reasonable using phoboes 
tools; but Im going to leave it as an open question before I get 
started on something from scratch.


Given well compliant phoboes-style ranges and a `ref string or 
retro!string` that starts with '(',')','[',']','{','}', modify 
that string so that you a) find the matching pair, b) return a 
list of indexs for where the top level commas are


"(foo([1,2]),bar!"\","foobar" => 
"(foo([1,2]),bar!"\","",[12]
retro("abc[1,2,3,4,"❤️❤️❤️❤️","\","]") => "[1,2,3,4,"❤️❤️❤️❤️","\","]", 
[2,4,6,8,35]


Re: mod of negative number

2024-09-24 Thread Timon Gehr via Digitalmars-d-learn

On 9/23/24 21:52, Craig Dillabaugh wrote:

Why does the following program:

     \
     import std.stdio;

     int main(string[] args) {
     uint Q = 7681;
     writeln("Val = ", -1 % Q);
     return 0;
     }
     \

     Print
     Val = 5568


Was hoping for 1.

I assume it is an integer promotion issue, but I am unsure how to 
resolve.  I tried replacing the Q with to!int(Q) but this gave me -1, 
which is closer but not right either.


Yes, what this does is to promote `-1` to `uint.max` and the result you 
are getting is `uint.max % 7686`.


`-1 % 7686` does not work because division rounds towards zero, so the 
result of modulo may be negative.


In general `a%b` will give you a value between `-abs(b)+1` and 
`abs(b)-1`, matching the sign of `a` (and ignoring the sign of `b`).


You can use something like `auto r=a%b; if(r<0) r+=abs(b);` or `auto 
r=(a%b+b)%b;`, depending an your needs (note that those two are not the 
same for negative `b`, but they match for positive `b`).


This implementation is equivalent to `(a%b+b)%b`, if you want to avoid 
the second modulo and the compiler is not smart enough:


```d
int floormod(int a,int b){
bool sign=(a<0)^(b<0);
auto r=a%b;
if(sign&&r!=0) r+=b;
return r;
}
```

The interpretation of this is to compute the remainder for a division 
that rounds to negative infinity.


Sometimes one might also want `a%0 = a`, but this is a special case that 
has to be checked as the language will give you a division by zero error.