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.