[OT] The Usual Arithmetic Confusions
Ola Fosheim Grøstad
ola.fosheim.grostad at gmail.com
Sat Jan 29 10:39:10 UTC 2022
On Saturday, 29 January 2022 at 01:06:45 UTC, Siarhei Siamashka
wrote:
> Modern programing languages tend to have separate operators or
> intrinsincs for wrapped and non-wrapped (trap on overflow)
> arithmetic operations.
Well, in C++ "unsigned int" is defined to have modular
arithmetics. The problem in C++ isn't that it is modular, but
that people use "unsigned int" as a value range type, rather than
when they want modular arithmetics. This is just a design
influenced by classic machine language instructions rather than
principled thoughts about math. This problem would probably have
been much less if the type had been named "modular int" and not
"unsigned int"! Syntax matters. :-D
In Ada I believe this is done explicitly, which clearly is much
better.
As for practical problems: In C++ you can still enable signed
overflow checks. In D you cannot even do that, because in D all
integer operations are defined to be modular.
Interestingly, the main complaint about modular arithmetics in
C++ is not about correctness however, but about poor
optimizations. As a result, thoughtfully designed C++ libraries
avoid using unsigned integers in interfaces.
Why are modular arithmetics performing worse than regular
arithmetics? It is often much more difficult (in some cases
impossible) to optimize computations that are mapped onto a
circle than computations that are mapped onto a straight line!
This is something that D should fix!!
> I think that it's only a matter of time until processors start
> adding the missing instructions to make this fast.
No. It isn't crazy slow because of the check. It is crazy slow
because it prevents optimizations in complex expressions.
In theory you could compute the overflow as a separate expression
and do speculative computations, then switch to a slow path on
overflow, but that would be more of a high level approach than a
system level approach. In low level programming the programmer
wants the code to map to machine language instructions without
blowing up the code size in ways that are hard to predict. You
want some transparency in how the code you write maps to the
hardware instructions.
To make overflow checks really cast you need a much more advanced
type system with constraints, so that the compiler can know what
values an integer picked up from the heap can have.
More information about the Digitalmars-d
mailing list