VRP and signed <-> unsigned conversion

Quirin Schroll qs.il.paperinik at gmail.com
Wed Dec 15 18:04:57 UTC 2021

On Wednesday, 15 December 2021 at 14:39:09 UTC, Steven 
Schveighoffer wrote:
> […]
> I'm wondering:
> 1. Does it make sense for this to be valid? Should we reexamine 
> unsigned <-> signed implicit casting?

I don't understand why `byte` should be implicitly convertible to 
`ubyte`. Seeing this as is, I think this is a bug.

> 2. If the above rewrite is possible, shouldn't VRP just allow 
> this conversion? i.e. a type that has an unsigned/signed 
> counterpart should be assignable if the signed/unsigned can 
> accept the range.

To me, it seems that VRP is designed around mathematical 
intuition in which the integer types are seen as {−2ⁿ⁻¹, …, 
2ⁿ⁻¹−1} and {0, …, 2ⁿ−1} for *n* appropriate. (I hope the Unicode 
superscripts render properly.)
The problem starts with subtraction. If *x, y* ∈ {0, …, 15}, then 
*x* − *y* ∈ {−15, …, 15}. A lot of professional people know that 
(at least the unsigned types) implement arithmetic modulo 2ⁿ, so 
*x* − *y* is well-defined. However, you *can* see unsigned types 
as positive types (e.g. when taking the length of an array); in 
this case, subtraction *x* − *y* makes no sense when *y* > *x*.
I guess the whole problem comes from the double-role unsigned 
types play: positive numbers vs. mod-2ⁿ numbers; a triple-role 
with bit-operations.

This is a fundamental design problem, and VRP cannot fix it. I 
don't know of a good solution, I've yet to see one. What I've 
never seen is splitting integers into *three* types: signed ones 
for {−2ⁿ⁻¹, …, 2ⁿ⁻¹−1}, unsigned ones for {0, …, 2ⁿ−1}, and 
bit-vectors for {0, 1}ⁿ. Bit operators would only be available 
for the latter, arithmetic for all of them, with the intuition 
that bit-vectors are mod-2ⁿ meaning that all operations are 
well-defined except division by zero, but for signed and unsigned 
types, all operations are partial (except unary plus). Even unary 
minus is partial for signed types because −(−2ⁿ⁻¹) ∉ {−2ⁿ⁻¹, …, 
2ⁿ⁻¹−1}. What (ideal) VRP can do is keep you from code that might 
leave the domain.
Another thing to note is that division in modular arithmetic is a 
bit weird: In mod-8 arithmetic, 7 ÷ 3 = 5 (as 3 × 5 = 15 ≡ 7), 
but virtually nobody wants that.

More information about the Digitalmars-d mailing list