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