<p dir="auto">Note: this is kind of a duplicate of <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="251657219" data-permission-text="Title is private" data-url="https://github.com/JuliaLang/julia/issues/23376" data-hovercard-type="issue" data-hovercard-url="/JuliaLang/julia/issues/23376/hovercard" href="https://github.com/JuliaLang/julia/issues/23376">#23376</a>, which was closed but no one had suggested this particular solution. Would the better etiquette have been to comment there instead of opening a new issue?</p>
<p dir="auto">The docstring for <code class="notranslate">isapprox()</code> gives a clear explanation of why it doesn't really work for one of the arguments be zero. However, I think there would be a lot of utility in including an <code class="notranslate">isapproxzero()</code> function that uses the same comparison method but the scale for <code class="notranslate">rtol</code> is set using an explicit argument. An example implementation would be as follows:</p>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="function isapproxzero(x, scale; atol::Real=0, rtol::Real=atol&gt;0 ? 0 : sqrt(eps()))
    norm(x) &lt;= atol + rtol * norm(scale)
end"><pre class="notranslate"><span class="pl-k">function</span> <span class="pl-en">isapproxzero</span>(x, scale; atol<span class="pl-k">::</span><span class="pl-c1">Real</span><span class="pl-k">=</span><span class="pl-c1">0</span>, rtol<span class="pl-k">::</span><span class="pl-c1">Real</span><span class="pl-k">=</span>atol<span class="pl-k">&gt;</span><span class="pl-c1">0</span> <span class="pl-k">?</span> <span class="pl-c1">0</span> <span class="pl-k">:</span> <span class="pl-c1">sqrt</span>(<span class="pl-c1">eps</span>()))
    <span class="pl-c1">norm</span>(x) <span class="pl-k">&lt;=</span> atol <span class="pl-k">+</span> rtol <span class="pl-k">*</span> <span class="pl-c1">norm</span>(scale)
<span class="pl-k">end</span></pre></div>
<p dir="auto">I ran into this when trying to check whether x is approximately fixed point of a function by checking the function's derivative is close to zero at that point, relative to the value of f(x). I think it's pretty broadly applicable, though.</p>
<p dir="auto">It would be convenient to have an <code class="notranslate">isapproxzero</code> method which is to <code class="notranslate">≈</code> what <code class="notranslate">iszero</code> is to <code class="notranslate">==</code>.<br>
In addition to being slighly more efficient than <code class="notranslate">isapprox</code>, <code class="notranslate">isapproxzero</code> would work out of the box with the default parameters.<br>
Indeed, since <code class="notranslate">atol</code> is zero by default we have for example:</p>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="julia&gt; 1e-100 ≈ 0
false"><pre class="notranslate">julia<span class="pl-k">&gt;</span> <span class="pl-c1">1e-100</span> <span class="pl-k">≈</span> <span class="pl-c1">0</span>
<span class="pl-c1">false</span></pre></div>
<p dir="auto">An implementation if <code class="notranslate">isapproxzero</code> could be</p>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="function isapproxzero(x::Number; rtol::Real=0, atol::Real=rtoldefault(typeof(x)), nans::Bool=false)
    iszero(x) || (isfinite(x) &amp;&amp; abs(x) &lt;= atol) || (nans &amp;&amp; isnan(x))
end"><pre class="notranslate"><span class="pl-k">function</span> <span class="pl-en">isapproxzero</span>(x<span class="pl-k">::</span><span class="pl-c1">Number</span>; rtol<span class="pl-k">::</span><span class="pl-c1">Real</span><span class="pl-k">=</span><span class="pl-c1">0</span>, atol<span class="pl-k">::</span><span class="pl-c1">Real</span><span class="pl-k">=</span><span class="pl-c1">rtoldefault</span>(<span class="pl-c1">typeof</span>(x)), nans<span class="pl-k">::</span><span class="pl-c1">Bool</span><span class="pl-k">=</span><span class="pl-c1">false</span>)
    <span class="pl-c1">iszero</span>(x) <span class="pl-k">||</span> (<span class="pl-c1">isfinite</span>(x) <span class="pl-k">&amp;&amp;</span> <span class="pl-c1">abs</span>(x) <span class="pl-k">&lt;=</span> atol) <span class="pl-k">||</span> (nans <span class="pl-k">&amp;&amp;</span> <span class="pl-c1">isnan</span>(x))
<span class="pl-k">end</span></pre></div>
<p dir="auto">It might be helpful to accept an <code class="notranslate">rtol</code> parameter even if it is not used since it allows to write functions like</p>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="function f(a, b, c; kws...)
    ... # do stuff
    isapprox(a, b; kws...)
    ... # do stuff
    isapproxzero(c; kws...)
    ... # do stuff
end"><pre class="notranslate"><span class="pl-k">function</span> <span class="pl-en">f</span>(a, b, c; kws<span class="pl-k">...</span>)
    <span class="pl-k">...</span> <span class="pl-c"><span class="pl-c">#</span> do stuff</span>
    <span class="pl-c1">isapprox</span>(a, b; kws<span class="pl-k">...</span>)
    <span class="pl-k">...</span> <span class="pl-c"><span class="pl-c">#</span> do stuff</span>
    <span class="pl-c1">isapproxzero</span>(c; kws<span class="pl-k">...</span>)
    <span class="pl-k">...</span> <span class="pl-c"><span class="pl-c">#</span> do stuff</span>
<span class="pl-k">end</span></pre></div>
<p dir="auto">Indeed if <code class="notranslate">isapproxzero</code> was not accepting <code class="notranslate">rtol</code>, this function would fail when <code class="notranslate">rtol</code> is given as a keyword to <code class="notranslate">f</code>.</p>