# Non-negative integers

**URL:** <https://discourse.julialang.org/t/non-negative-integers/59008>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [April 10, 2021, 8:23pm UTC](https://discourse.julialang.org/t/non-negative-integers/59008 "2021-04-10T20:23:45Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [April 10, 2021, 8:23pm UTC](https://discourse.julialang.org/t/non-negative-integers/59008/1 "2021-04-10T20:23:46Z")

</div>

I want to do some things with non-negative integers and use it in function signatures. Is this idiomatic?

```julia
# Concrete subtypes should have a `val` attribute.
abstract type NonNegativeInteger <: Integer end

struct NonNegativeInt{T} <: NonNegativeInteger
    val::T
end

Base.:+(x::T, y::T) where T <: NonNegativeInteger = T(x.val + y.val)
Base.:*(x::T, y::T) where T <: NonNegativeInteger = T(x.val * y.val)
Base.:^(x::T, y::T) where T <: NonNegativeInteger = T(x.val ^ y.val)

a = NonNegativeInt(2)
b = NonNegativeInt(3)
(a + b, a * b, a ^ b)

```

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [April 10, 2021, 8:42pm UTC](https://discourse.julialang.org/t/non-negative-integers/59008/2 "2021-04-10T20:42:40Z")

</div>

Out of curiosity, why not using `UInt*` types?

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [April 10, 2021, 8:52pm UTC](https://discourse.julialang.org/t/non-negative-integers/59008/3 "2021-04-10T20:52:04Z")

</div>

I could probably use `SaferIntegers.UInt`. So maybe nonnegative real/rational/float would be a better example to ask the question with.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [April 10, 2021, 9:45pm UTC](https://discourse.julialang.org/t/non-negative-integers/59008/4 "2021-04-10T21:45:23Z")

</div>

> [@jzr](#):
>
> So maybe nonnegative real/rational/float would be a better example to ask the question with.

There isn’t such a type for floating-point numbers; you could define one, of course, but this is something that’s probably better done with a runtime argument check:

```julia
function f(x::Real)
     x ≥ 0 || throw(DomainError("negative x=$x not allowed"))
    ...
end

```

Note that if `x` is an `Unsigned` type (like `UInt`, and also things like `Rational{UInt}`), the compiler will know that `x ≥ 0` is always `true` and optimize out the check.

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [April 11, 2021, 6:23am UTC](https://discourse.julialang.org/t/non-negative-integers/59008/5 "2021-04-11T06:23:12Z")

</div>

Is `>= 0` a special case, or can I somehow make my own compiler-optimized predicates?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [April 11, 2021, 12:55pm UTC](https://discourse.julialang.org/t/non-negative-integers/59008/6 "2021-04-11T12:55:27Z")

</div>

> [@jzr](#):
>
> Is `>= 0` a special case, or can I somehow make my own compiler-optimized predicates?

`≥ 0` is not a special case, in the sense that the compiler (LLVM) does [constant folding](https://en.wikipedia.org/wiki/Constant_folding) and [dead-code elimination](https://en.wikipedia.org/wiki/Dead_code_elimination) on any predicate that is inlined (any sufficiently short function). Whether this results in an elided check depends on what you are doing and the limits of LLVM.
