www.gusucode.com > mbcdata 工具箱 matlab 源码程序 > mbcdata/@cgprecfloat/phys2hw.m

    function HWValues = phys2hw(Prec, PhysValues)
%PHYS2HW  Convert physical representation to achievable
%   floating point hardware representation
%
%   HWValues = PHYS2HW(FLOATPREC, PhysValues) converts unresolved physical
%   values PhysValues to achievable floating point hardware values HWValues
%   using the achievable resolution specified by the cgprecfloat object
%   FLOATPREC.

%   Copyright 2000-2006 The MathWorks, Inc. and Ford Global Technologies, Inc.


% Error check on PhysValues
PhysValues = i_check(Prec, PhysValues, 'PhysValues');

% Clip the physical values to range specified by PhysRange
PhysRange = get(Prec, 'PhysRange');
PhysValues(PhysValues<PhysRange(1)) = PhysRange(1);
PhysValues(PhysValues>PhysRange(2)) = PhysRange(2);

% Get mantissa size and exponent size from cgprecfloat object
mbits = get(Prec, 'mbits');
ebits = get(Prec, 'ebits');

% Work with the magnitude of the raw values rather than the raw values
% themselves.  This simplifies the operations considerably since the
% calculation of the exponent involves logarithms.
AbsPhysValues = abs(PhysValues);

% Calculate the maximum and minimum exponent.  The minimum exponent is set to
% -2^(ebits-1) rather than 1-2^(ebits-1) to simplify the treatment of
% underflow.
minexponent = -2^(ebits-1);
maxexponent = 2^(ebits-1);

% Initialise HWValues.exponent array
HWValues.exponent = zeros(size(PhysValues));

ZeroVals = (AbsPhysValues==0);
InfVals = isinf(AbsPhysValues);
FiniteVals = isfinite(AbsPhysValues);
NonZeroFiniteVals = FiniteVals & ~ZeroVals;

% Calculate exponents of nonzero finite physical values
HWValues.exponent(NonZeroFiniteVals) = ...
    floor(log2(AbsPhysValues(NonZeroFiniteVals)));

% Set exponents of zero physical values
HWValues.exponent(ZeroVals) = -Inf;

% Adjust exponents to fit minimum and maximum achievable values in hardware
HWValues.exponent((HWValues.exponent<minexponent) & ...
    (~isinf(HWValues.exponent))) = minexponent;
HWValues.exponent(HWValues.exponent>maxexponent) = maxexponent;

% Define the maximum and minimum mantissa
minmantissa = 0;
maxmantissa = 1;

% Initialise HWValues.mantissa array
HWValues.mantissa = zeros(size(PhysValues));

% Calculate exponents of nonzero physical values
HWValues.mantissa(NonZeroFiniteVals) = ...
    round((2^mbits)*(AbsPhysValues(NonZeroFiniteVals)- ...
    (2.^HWValues.exponent(NonZeroFiniteVals)))./ ...
    (2.^HWValues.exponent(NonZeroFiniteVals)))/(2^mbits);

% Adjust exponents to fit minimum and maximum achievable values in hardware
HWValues.mantissa(HWValues.mantissa<minmantissa) = minmantissa;
HWValues.mantissa(HWValues.mantissa>maxmantissa) = maxmantissa;

% Overflow
HWValues.mantissa((HWValues.mantissa==maxmantissa) & ...
    (HWValues.exponent==maxexponent)) = 1-1/2^(mbits);

% Tidy up the exponent and mantissa for the case where mantissa = 1
% by incrementing the exponent and resetting the mantissa to 0
HWValues.exponent(HWValues.mantissa==1) = ...
    HWValues.exponent(HWValues.mantissa==1)+1;
HWValues.mantissa(HWValues.mantissa==1) = 0;

% Underflow - identify the values to round down
HWValues.exponent(AbsPhysValues<(2^minexponent)) = -Inf;
HWValues.mantissa(AbsPhysValues<(2^minexponent)) = 0;

% Underflow - identify the values to round up
HWValues.exponent((AbsPhysValues>=(2^minexponent)) & ...
    (AbsPhysValues<(2^(1+minexponent)))) = minexponent+1;
HWValues.mantissa((AbsPhysValues>=(2^minexponent)) & ...
    (AbsPhysValues<(2^(1+minexponent)))) = 0;

% Set mantissa for non-finite values
HWValues.mantissa(InfVals) = Inf;
HWValues.mantissa(~FiniteVals & ~InfVals) = NaN;

% Set sign bit
HWValues.sign = zeros(size(PhysValues));
HWValues.sign(FiniteVals | InfVals) = sign(PhysValues(FiniteVals | InfVals));


% -------------------------------------------------------------------------
function out = i_check(Prec, in, VarName)

% Check input variables
switch VarName
    case 'PhysValues'
        if pCheckNumeric(Prec, in, true, 'PhysValues')
            % Value is valid
            out = in;
        end
end