function r = eps(x)
%MATLAB Code Generation Library Function

%   Copyright 2002-2019 The MathWorks, Inc.
%#codegen

coder.internal.allowHalfInputs;
if nargin == 0
    x = 'double';
    CLASSINPUT = true;
    HALFINPUT = false;
elseif coder.internal.isTextRow(x)
    coder.internal.prefer_const(x);
    CLASSINPUT = true;
    % Could easily support eps('half') here by defining
    % HALFINPUT = isa(x,'half').
    HALFINPUT = false;
    coder.internal.assert(coder.internal.isFloatClass(x) || HALFINPUT, ...
        'MATLAB:eps:invalidClass');
else
    CLASSINPUT = false;
    HALFINPUT = isa(x,'half');
    coder.internal.assert(isa(x,'float'), ...
        'MATLAB:eps:invalidClass');
end
if CLASSINPUT
    r = coder.const(coder.internal.eps(x));
else
    % Except for denormals, if 2^E <= ABS(X) < 2^(E+1), then
    %   EPS(X) = 2^(E-23) if ISA(X,'single')
    %   EPS(X) = 2^(E-52) if ISA(X,'double')
    r = coder.nullcopy(real(x));
    MANTISSALENGTH = coder.const(coder.internal.mantissa_nbits(class(x)));
    if HALFINPUT
        REALMIN = coder.const(single(coder.internal.realmin(class(x))));
    else
        REALMIN = coder.const(coder.internal.realmin(class(x)));
    end
    MINEPS = coder.const(eml_realmin_denormal(class(x)));
    if HALFINPUT
        for k = 1:numel(x)
            r(k) = scalarEps(single(x(k)),REALMIN,MINEPS,MANTISSALENGTH);
        end
    else
        for k = 1:numel(x)
            r(k) = scalarEps(x(k),REALMIN,MINEPS,MANTISSALENGTH);
        end
    end
end

%-------------------------------------------------------------------------------

function r = scalarEps(x,REALMIN,MINEPS,MANTISSALENGTH)
coder.inline('always');
coder.internal.prefer_const(REALMIN,MINEPS,MANTISSALENGTH);
r = coder.nullcopy(real(x));
absx = abs(x);
rONE = ones('like',real(r));
if isfinite(absx)
    if absx <= REALMIN
        r(1) = MINEPS;
    else
        [~,exponent] = eml_frexp(absx);
        exponent = eml_minus(exponent,MANTISSALENGTH,'int32','spill');
        r(1) = eml_ldexp(rONE,exponent);
    end
else
    r(1) = coder.internal.nan;
end

%-------------------------------------------------------------------------------
