operator_precedence is about binary operators, and larger numbers have higher precedence.
So, when it is treated as a binary operator, ~ has the lowest precedence, the same as assignment =:
julia> Base.operator_precedence(:(=))
1
julia> Base.operator_precedence(:(~))
1
And indeed, you can define ~ as a binary function:
julia> :(a ~ b)
:(a ~ b)
julia> Base.:(~)(a, b) = a + b
julia> 3 ~ 4
7
The reason that it has assignment precedence was mainly intended for domain-specific languages via metaprogramming/macros, since ~ has an “assignment-like” meaning in statistics. In fact, ~ was originally a special “metaprogramming-only” binary operator that expanded into a macro call: Make tilde automatically quote its arguments · Issue #4882 · JuliaLang/julia · GitHub
Unary operator precedence, on the other hand, is handled differently, and unary operators are higher precedence than * but are trickier for ^. See e.g.
… this is something that could be documented better. (clarify Base.operator_precedence docs: this is only for binary operators by stevengj · Pull Request #60087 · JuliaLang/julia · GitHub … other PRs could improve other portions of the documentation of this kind of thing.)