I need to take differences of unsigned numbers. For that purpose I propose to add a
signed_sub function, that subtracts UInts, producing a (signed) Int result. For UInt64, it would be:
function signed_sub(x::UInt64, y::UInt64) reinterpret(Int64, x - y) end
That’s straightforward. But what I really want is the overflow-checked version, which was trickier to write:
function checked_signed_sub(x::UInt64, y::UInt64) r, f = Base.sub_with_overflow(x, y) # f is the sign of the 65-bit result. # When we reinterpret, the top bit becomes the sign. # So overflow is when those differ. f ⊻ Core.is_top_bit_set(r) && Base.Checked.throw_overflowerr_binaryop(:signed_sub, x, y) reinterpret(Int64, r) end
If there is agreement on the functionality (and the names) I’ll make a PR to add it as generally as I can (for all Unsigned types). (I’m happy if someone else wants to do it. I don’t know a good way to get the signed version of an unsigned type. I’d probably just make a Dict, but maybe there is a better way?)
I considered the dual, taking signed integers and producing an unsigned result, but I couldn’t imagine a use for that.