&gt; In my case, I was designing a spec for a CPU that was intended to be as minimal as possible. The CPU would physically implement signed or unsigned atomic math operations, not both. The compiler would support the missing one (signed or unsigned) using emulation in terms of the one that was physically implemented.<p>I find that part very strange.  Here are a couple of observations:<p>* Unsigned wrapping binary addition and two&#x27;s complement addition are identical as long as you don&#x27;t try to report carry or overflow.<p>* Unsigned wrapping binary subtraction and two&#x27;s complement subtraction are identical as long as you don&#x27;t try to report borrow or underflow.  If the goal is absolute simplicity, subtraction isn&#x27;t needed at all because both cases are efficiently handled by two&#x27;s complement negation  (which is the same thing as calculating 0-x in an unsigned wrapping sense) followed by addition.<p>* Unsigned wrapping binary non-widening multiplication (the usual case) and two&#x27;s complement multiplication are identical.  This follows from the distributive law: an n-bit two&#x27;s complement negative number -x is represented as 2^n - x.  If you multiply -x (a two&#x27;s complement number interpreted as unsigned) by y, you end up with (2^n - x) * y, which is y<i>2^n - x</i>y.  The first term doesn&#x27;t affect the result, because its low bits are all zero.<p>Widening multiplication is extremely useful, but implementing the unsigned version in hardware should make it fairly simple to emulate the signed version.  x86 implements both.<p>Division is nasty, especially because number theorists and C programmers disagree on what it means when negative numbers are involved.  Really simple CPUs don&#x27;t implement division at all, though.<p>Finally, CPU vendors who actually implement undefined behavior are, in my opinion, nuts.  Give the CPU a nice clean spec that fully defines what happens and stick to it.