# Proposed signed\_sub function

**URL:** <https://discourse.julialang.org/t/proposed-signed-sub-function/54766>\
**Category:** Internals & Design\
**Created:** [February 7, 2021, 12:04am UTC](https://discourse.julialang.org/t/proposed-signed-sub-function/54766 "2021-02-07T00:04:03Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![bobcassels](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bobcassels/32/14586_2.png) [@bobcassels](https://discourse.julialang.org/u/bobcassels)\
**Post date:** [February 7, 2021, 12:04am UTC](https://discourse.julialang.org/t/proposed-signed-sub-function/54766/1 "2021-02-07T00:04:03Z")

</div>

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:

```julia
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:

```julia
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.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [February 7, 2021, 3:16pm UTC](https://discourse.julialang.org/t/proposed-signed-sub-function/54766/2 "2021-02-07T15:16:26Z")

</div>

I think this should go in a package first, the very least until the API stabilizied, and then it should be considered for `Base` if it is (1) widely used and (2) stable.

The biggest problem I see is supporting generic types (related to your question): if a package defined `T <: Unsigned`, how to they hook into `signed_sub`? Requiring that all such types define a method for such a niche use case may not be worth it.

---

<div class="post-metadata">

**Author:** ![klaff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/klaff/32/7637_2.png) [@klaff](https://discourse.julialang.org/u/klaff)\
**Post date:** [February 7, 2021, 3:30pm UTC](https://discourse.julialang.org/t/proposed-signed-sub-function/54766/3 "2021-02-07T15:30:02Z")

</div>

Have you considered [https://github.com/JeffreySarnoff/SaferIntegers.jl](https://github.com/JeffreySarnoff/SaferIntegers.jl) for your needs?

---

<div class="post-metadata">

**Author:** ![bobcassels](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bobcassels/32/14586_2.png) [@bobcassels](https://discourse.julialang.org/u/bobcassels)\
**Post date:** [February 7, 2021, 3:57pm UTC](https://discourse.julialang.org/t/proposed-signed-sub-function/54766/4 "2021-02-07T15:57:56Z")

</div>

Good to know about this. Thanks!

---

<div class="post-metadata">

**Author:** ![bobcassels](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bobcassels/32/14586_2.png) [@bobcassels](https://discourse.julialang.org/u/bobcassels)\
**Post date:** [February 7, 2021, 4:24pm UTC](https://discourse.julialang.org/t/proposed-signed-sub-function/54766/5 "2021-02-07T16:24:09Z")

</div>

I see and appreciate most of your points. I was only considering the builtin subtypes of `Unsigned`, where I’m willing to define the result type.

I don’t understand your "Requiring that all such types define a method " comment. I was trying to parallel the existing `Base.checked_sub`. What am I missing?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [February 8, 2021, 12:21pm UTC](https://discourse.julialang.org/t/proposed-signed-sub-function/54766/6 "2021-02-08T12:21:03Z")

</div>

Imagine that a third-party packages defines a new type `CustomUnsigned <: Unsigned`. Should it define a method of `Base.checked_signed_sub` for this type?

If yes, then it adds to the complexity of the interface. If not, then it cannot be used in generic code.

This is a trade-off and the cost should be considered relative to the benefit. IMO this is a pretty niche use case and should be supported in a package (for types in `Base`, but YMMV).

---

<div class="post-metadata">

**Author:** ![bobcassels](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bobcassels/32/14586_2.png) [@bobcassels](https://discourse.julialang.org/u/bobcassels)\
**Post date:** [February 8, 2021, 1:25pm UTC](https://discourse.julialang.org/t/proposed-signed-sub-function/54766/7 "2021-02-08T13:25:58Z")

</div>

Got it. I agree this is a niche case. I have been a developer for many years, and this is the first time I’ve wanted such a thing.

On the other hand, when I wanted it, it took me many hours reading through `Base` code to figure out how to implement it efficiently. I imagine that would be the case for most users of the `checked_...` functions. So I wanted to capture that knowledge. I’m fine with making it a package.

On the other other hand, I’m now thinking that for my particular use case, I can define my `signed_sub` as returning a signed type of the next larger precision. That can’t overflow so I don’t need `checked_signed_sub`, and makes `signed_sub` very different from `checked_sub` and the other checked functions. But I do not need the other checked functions for my application. So I will go ahead and make the package we are talking about eventually, but with lower priority.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [February 8, 2021, 1:29pm UTC](https://discourse.julialang.org/t/proposed-signed-sub-function/54766/8 "2021-02-08T13:29:50Z")

</div>

> [@bobcassels](#):
>
> define my `signed_sub` as returning a signed type of the next larger precision.

Generally, if I need signed differences, I would go with a signed type.

It is very rare that the extra bit of range I get out of an `Unsigned` type with the same number of bits is crucial.

---

<div class="post-metadata">

**Author:** ![bobcassels](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bobcassels/32/14586_2.png) [@bobcassels](https://discourse.julialang.org/u/bobcassels)\
**Post date:** [February 9, 2021, 12:28am UTC](https://discourse.julialang.org/t/proposed-signed-sub-function/54766/9 "2021-02-09T00:28:45Z")

</div>

Of course. As I mentioned, I have not wanted it until now. In my case, I have implemented a timestamp with nanosecond precision (using the Unix epoch as a base). And I want to take signed differences between these timestamps. I have no need for times before the Unix epoch, so using UInt64 gives me a wider range. I will admit that it probably makes no practical difference, but it makes me feel better.

```julia
julia> Timestamp(typemax(UInt64))
2554-07-21T23:34:33.709551615

julia> Timestamp(typemax(Int64))
2262-04-11T23:47:16.854775807

```
