function pibar(name,exact,pos,digits)
    % pibar
    % Usage: pibar
    %        pibar(name)
    %        pibar(name,exact)
    %        pibar(name,exact,[x,y,w,h])
    %        pibar(name,exact,[x,y,w,h],digits)
    %
    % Defaults: pibar('pi',4*atan(1),[.4 .5 .4 .05],10)
    % Examples: pibar('golden',(1+sqrt(5))/2)
    %           pibar('100/81',100/81)
    % Blog: Google "cleve blog pibar".
    
    %   Copyright 2020 Cleve Moler
    %   Copyright 2020 The MathWorks, Inc.

    warning('off','MATLAB:dispatcher:nameConflict')
    clf

    if nargin < 1
        name = 'pi';
    end
    
    if nargin < 2
        exact = 4*atan(1);
    end
    
    if nargin < 3
        pos = [.4 .5 .4 .05];
    end

    if nargin < 4
        digits = 10;
    end
    
    uicontrol('style','slider', ...
        'units','normal', ...
        'position',pos-[0 .05 0 0], ...
        'min',-digits, ...
        'max',digits, ...
        'value',0, ...
        'sliderstep',[0.5/digits 0.5/digits], ...
        'tag','pibar', ...
        'userdata',exact, ....
        'callback',@pibar_callback);
    txt = uicontrol('style','text', ...
        'string',spintf(exact), ...
        'units','normal', ...
        'position',pos, ...
        'fontsize',get(groot,'defaultuicontrolfontsize')+2, ...
        'horiz','left');
    uicontrol('style','text', ...
        'string','^', ...
        'units','normal', ...
        'pos',[pos(1)+.47*pos(3) pos(2)-.075 .025 .025], ...
        'fontsize',12);
    
    warning('on','MATLAB:dispatcher:nameConflict')

    % --------------------------------------------------------------
   
    function pibar_callback(arg,~)
        % Perturbation of exact.
        % Logarithmic integer-valued slider.
        d = round(get(arg,'value'));
        set(arg,'value',d);
        s = 10^(digits+1-abs(d));
        if d > 0
            x = ceil(s*exact)/s;
        elseif d < 0
            x = floor(s*exact)/s;
        else
            x = exact;
        end
        set(arg,'userdata',x)
        set(txt,'string',spintf(x)) 
    end

    function spi = spintf(x)
        if x == exact
            spi = sprintf('%s = %17.15f....',name,x);
        else
            d = digits+1 - abs(get(findobj('tag','pibar'),'value'));
            fmt = [name ' = %' num2str(d+2) '.'  num2str(d) 'f'];
            spi = sprintf(fmt,x);
        end 
    end
end



function p = pi
    % pi.  The current setting of the pibar.
    warning('off','MATLAB:dispatcher:nameConflict')
    p = get(findobj('tag','pibar'),'userdata');
    warning('on','MATLAB:dispatcher:nameConflict')    
end


function t = truepi
    % The double precision floating number closest to Geek letter pi.
    % The usual value of MATLAB's pi.
    %  See also : pibar.
    t = 4*atan(1);
end