# The new \`invmod(n, T)\` function and even arguments

**URL:** <https://discourse.julialang.org/t/the-new-invmod-n-t-function-and-even-arguments/118377>\
**Category:** General Usage\
**Created:** [August 19, 2024, 4:54pm UTC](https://discourse.julialang.org/t/the-new-invmod-n-t-function-and-even-arguments/118377 "2024-08-19T16:54:22Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ken\_Williams](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ken_williams/32/5289_2.png) [@Ken\_Williams](https://discourse.julialang.org/u/Ken_Williams)\
**Post date:** [August 19, 2024, 4:54pm UTC](https://discourse.julialang.org/t/the-new-invmod-n-t-function-and-even-arguments/118377/1 "2024-08-19T16:54:22Z")

</div>

I was reading about new features in Julia 1.11 and happened upon this new `invmod` capability: [invmod(n::BitInteger): efficient native modular inverses by StefanKarpinski · Pull Request #52180 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/52180) .

As someone more accustomed to math than bit-twiddling, I didn’t realize at first that this is doing modular inverses in base `2^N` (determined by the max values of the type `T`) and thus the argument must be odd to have a well-defined inverse. It would be great to add that requirement to the docs, and document what happens when the argument is even (a `DomainError` exception appears to be the result).

Also, for consistency with other ares where an inverse doesn’t exist (e.g. computing `1/0` and getting `Inf`), I wonder whether throwing an exception might not be the best option. Is there a suitable non-value in Julia for this situation? That might help callers who’d want to do `invmod.(array)` on a bunch of values at once, for example.

Finally, I noticed that the unit tests don’t seem to limit themselves to odd values, but they don’t seem to worry about catching the `DomainError` exception either - how does this work?

---

<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:** [August 19, 2024, 5:53pm UTC](https://discourse.julialang.org/t/the-new-invmod-n-t-function-and-even-arguments/118377/2 "2024-08-19T17:53:23Z")

</div>

A documentation PR to clarify this would be welcome, I suspect. The [documentation for `invmod(n)` is here](https://github.com/JuliaLang/julia/blob/39eaa3cfc1a861cf898d89fbe320ffa858f41939/base/intfuncs.jl#L261-L267), and you can click the [edit button](https://docs.github.com/en/repositories/working-with-files/managing-files/editing-files) to edit it and submit a PR directly from the browser.

Note that [the `invmod(n, m)` docs](https://github.com/JuliaLang/julia/blob/39eaa3cfc1a861cf898d89fbe320ffa858f41939/base/intfuncs.jl#L225-L226) explicitly say that an error is thrown if the multiplicative inverse \mod m doesn’t exist, so it would make sense `invmod(n)` to have a documentation comment in a similar form.

> [@Ken\_Williams](#):
>
> Is there a suitable non-value in Julia for this situation?

Not if you want to return a machine integers, and returning a different type of value (e.g. `Inf` or `nothing`) would not be [type-stable](https://docs.julialang.org/en/v1/manual/performance-tips/#Write-%22type-stable%22-functions).

> [@Ken\_Williams](#):
>
> Finally, I noticed that the unit tests don’t seem to limit themselves to odd values

Yes [they](https://github.com/JuliaLang/julia/blob/39eaa3cfc1a861cf898d89fbe320ffa858f41939/test/intfuncs.jl#L269-L298) do. The loop `for a = typemin(T)+true:T(2):typemax(T)` goes in steps of `2`, so it only covers odd integers. The randomized tests use `a = rand(T) | true`, where the bitwise or `|` with `true == 1` sets the last bit of `a`, making it odd.

---

<div class="post-metadata">

**Author:** ![Ken\_Williams](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ken_williams/32/5289_2.png) [@Ken\_Williams](https://discourse.julialang.org/u/Ken_Williams)\
**Post date:** [August 19, 2024, 8:45pm UTC](https://discourse.julialang.org/t/the-new-invmod-n-t-function-and-even-arguments/118377/3 "2024-08-19T20:45:59Z")

</div>

Ah! I was wondering what that `| true` was doing in there, I overlooked the fact that it was a bitwise operator and not a logical check.

I’ve created a PR here ([Add behavior for even values to docs for new invmod(n, T) functions by kenahoo · Pull Request #55531 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/55531)), thanks for the advice.
