起因

由于matlab中不存在科学计数法来表示一个数字,因此为了将例如1234567这个数字转换为1.234567M,需要自己实现一个装饰器,将其应用到fprintf函数中。

实现方式

代码如下

function outFunction = fprintfSciDecorator(inFunction)
% Usage:
%    fprintfSci = fprintfSciDecorator(@fprintf);
%    fprintfSci('   Freq = %sHz\n', 123456789);
    arguments
    	inFunction (1,1) function_handle
    end
    outFunction = @(varargin) decorate(inFunction, varargin{:});
    
    function varargout = decorate(fun, varargin)
    	ins = cell(1, numel(varargin));
        ins{1} = varargin{1};
        for index = 2:numel(varargin)
        	unit_num = varargin{index};
            if unit_num < 1e-21
            	ins{index} = [num2str(unit_num/1e-21, 5), 'y '];
            elseif unit_num >= 1e-21 & unit_num < 1e-18
            	ins{index} = [num2str(unit_num/1e-21, 5), 'z '];
            elseif unit_num >= 1e-18 & unit_num < 1e-15
            	ins{index} = [num2str(unit_num/1e-18, 5), 'a '];
            elseif unit_num >= 1e-15 & unit_num < 1e-12
            	ins{index} = [num2str(unit_num/1e-15, 5), 'f '];
            elseif unit_num >= 1e-12 & unit_num < 1e-09
            	ins{index} = [num2str(unit_num/1e-12, 5), 'p '];
            elseif unit_num >= 1e-09 & unit_num < 1e-06
            	ins{index} = [num2str(unit_num/1e-09, 5), 'n '];
            elseif unit_num >= 1e-06 & unit_num < 1e-03
            	ins{index} = [num2str(unit_num/1e-06, 5), 'u '];
            elseif unit_num >= 1e-03 & unit_num < 1e00
            	ins{index} = [num2str(unit_num/1e-03, 5), 'm '];
            elseif unit_num >= 1e00 & unit_num < 1e03
            	ins{index} = [num2str(unit_num/1e00, 5), ' '];
            elseif unit_num >= 1e03 & unit_num < 1e06
            	ins{index} = [num2str(unit_num/1e03, 5), 'k '];
            elseif unit_num >= 1e06 & unit_num < 1e09
            	ins{index} = [num2str(unit_num/1e06, 5), 'M '];
            elseif unit_num >= 1e09 & unit_num < 1e12
            	ins{index} = [num2str(unit_num/1e09, 5), 'G '];
            elseif unit_num >= 1e12 & unit_num < 1e15
            	ins{index} = [num2str(unit_num/1e12, 5), 'T '];
            elseif unit_num >= 1e15 & unit_num < 1e18
            	ins{index} = [num2str(unit_num/1e15, 5), 'P '];
            elseif unit_num >= 1e18 & unit_num < 1e21
            	ins{index} = [num2str(unit_num/1e18, 5), 'E '];
            elseif unit_num >= 1e21 & unit_num < 1e24
            	ins{index} = [num2str(unit_num/1e21, 5), 'Z '];
            else
            	ins{index} = [num2str(unit_num/1e21, 5), 'Y '];
            end
        end
        [varargout{1:nargout}] = fun(ins{:});
    end
end

当使用的时候,首先需要进行声明。

fprintfSci = fprintfSciDecorator(@fprintf);

然后再按照fprintf的方式正常调用即可。

fprintfSci('   Freq = %sHz\n', 123456789);

参考文献

  1. A special custom attribute: Decorators