具有独立 bits/digits 计算的 dec2base

dec2base with independent bits/digits calculation

需要MATLAB/Octavedec2base 具有独立 bits/digits 计算算法的功能函数(在 整数 逻辑中,没有除法,使用模块化算法)。

也很高兴:

  1. 匿名函数

注意! 浮点逻辑和除法只能用于标量一次,以定义转换后的数字数组中的最大位数:

ceil( log2(max(dec(:)))/log2(base)) )

最佳答案:

P.S.

  1. 简化 dec2bin 案例的解决方案 .
  2. 此 post 中提供的 bitget 的解决方案:
  1. MATLAB / OCTAVE:

    % For Matlab/Octave: 
    de2bs = @(dec,base) base.^([(1+floor( log2(max(dec(:)))/log2(base)) ):-1:1]-1); % an array of powers of a base
    de2bs = @(dec,base) sum(rem(dec(:)                                ...
                               ,base.*de2bs(dec,base)                 ...
                               )                                      ...
                            >=permute((1:base-1)'*(de2bs(dec,base))   ...
                                     ,[3,2,1]                         ...
                                     )                                ...
                            ,3                                        ...
                            );          
    

    示例:

    x=0:9; base=3; de2bs(x,base)
    
    ans =
    
    0   0   0
    0   0   1
    0   0   2
    0   1   0
    0   1   1
    0   1   2           
    0   2   0
    0   2   1
    0   2   2
    1   0   0
    
  2. 仅在 OCTAVE 中:就 Octave 支持匿名的默认值而言 函数,还有一个更有趣的重载函数 实施:

    % OCTAVE only (Matlab do not support default values for parameters)
    
    % Anonymous function de2bs
    % dig = digget(dec, base, isoutputasstring, pos)                
    %   dig  - returns the value of the digits in positions (pos) for numbers (dec)
    %          coverted to the defined base (for base=2 behaves similar to bitget) 
    %   dec  - mandatory, initial decimal numbers vector
    %   base - optional (by default base = 2),
    %          base to convert (for binary base = 2 )
    %   isoutputasstring - optional (by default isoutputasstring = true), 
    %          example: de2bs(26,16,0) -> '1A'
    %          example: de2bs(26,16,1) -> [1 10]%   
    %   pos  - optional (by default pos = (ceil( log2(max(dec(:)))/log2(base)) ):-1:1 ) 
    %          array of positions (like in bitget function)
    
    de2bs = @(dec
            ,base = [2]                                                  ... % Base of numbers you want to get
            ,isoutputinstringformat = [true]                             ... % output format 0/1 - integer/string 
            ,pos  = [(ceil( log2(max(dec(:)))/log2(base)) ):-1:1]        ... % Bits/digits positions to return (similar to bitget function)
        ... % temporary variables listed below (NOT parameters)          ...
            ,pbs  = [base.^(pos-1)]                                      ... % pbs - powers of base
            ,num  = [sum(rem(dec(:)                                      ... % conversion to defined base
                            ,base.*pbs                                   ...
                            )                                            ...
                        >= permute((1:base-1)'*pbs                       ...
                                  ,[3,2,1]                               ...
                                  )                                      ...
                        ,3                                               ...
                        )                                                ...
                    ]                                                    ...
            )                                                            ...
            ifelse(isoutputinstringformat                                ... % Convert digits to chars if necessary
                  ,char(ifelse(num>9,num+55, num+48))                    ... % like 9->'9', 10->'A', 11->'B';
                  ,num                                                   ... 
                  );
    

    示例:

    x=25:28;
    base=16;
    
    
    de2bs(x)        % behaves as dec2bin(x)
    
    ans =
    
    11001
    11010
    11011
    11100        
    
    
    de2bs(x,base)   % behaves as dec2base(x,base)
    
    ans =
    
    19
    1A
    1B
    1C
    
    
    de2bs(x,base,0) % behaves as dec2base(x,base) without converting/mapping to string/char format
    
    ans =
    
    1    9
    1   10
    1   11
    1   12
    
    
    de2bs(x,base,1,[3 2 1])   % behaves as dec2base(x,base), but returns mentioned digits in number (like in bitget function)
    
    ans =
    
    019
    01A
    01B
    01C
    

如果您需要它作为常规函数(需要支持 Compatible Array Sizes for Basic OperationsMatLab 版本):

function dig = de2bs(dec, base, isoutputnumerical, pos) 
% de2bs(D)
% de2bs(D, BASE)
% de2bs(D, BASE, ISOUTPUTNUMERICAL)  
% de2bs(D, BASE, ISOUTPUTNUMERICAL, POS)
%
% de2bs(D)
%     Return a binary number corresponding to the non-negative integer D
%     (Behaves the same as dec2bin(D) )
%     
%         de2bs([123,321])  
%         ans = 001111011
%               101000001
%
% de2bs(D, BASE)
%     Return a string of symbols in base BASE corresponding 
%     to the non-negative integer D.
%     
%         de2bs(123, 3)  
%         ans = 011120
%               102220
%  
%     If BASE is a string then the base is calculated as length(BASE),
%     and characters of BASE are used as the symbols for the digits of D.  
%
%          de2bs (123, "aBc")
%          ans = aBBBca
%                Baccca
% 
% de2bs(D, BASE, ISOUTPUTNUMERICAL)  
%     By default, ISOUTPUTNUMERICAL is false   
%
%          de2bs([123,321],16,0) 
%          ans = 07B
%                141
%
%          de2bs([123,321],16,1) 
%          ans = 0    7   11
%                1    4    1
%
%
% de2bs(D, BASE, ISOUTPUTNUMERICAL, POS)
%     POS  - optional array of digits positions (like in bitget function)
%            By default pos = (ceil( log2(max(dec(:)))/log2(base)) ):-1:1 ) 
%
%          dde2bs([123,321],3,0)          
%          ans = 011120
%                102220
%           
%          de2bs([123,321],3,0,8:-2:2)
%          ans = 0012
%                0122
%
% See also: dec2base, base2dec, dec2bin, dec2hex.


% parsing input parameters ------------------------------------------
if nargin < 2  base = 2; end

symbols = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

if (ischar(base))  symbols = base;  base = length(symbols); end
if  nargin < 3  isoutputnumerical = false; end

max_len = ceil( log2(max(dec(:)))/log2(base));

if  nargin < 4  pos = [max_len:-1:1]; end


% Conver decimals into base -----------------------------------------
pbs = [base.^(pos-1)];        % pbs - powers of base
dig = sum(rem(dec(:), base.*pbs) >= permute((1:base-1)'*pbs,[3,2,1]),3);    % TODO - with for loop requires less calculations (this is just example with compact code)

if isoutputnumerical == false  dig = reshape(symbols(dig+1), size(dig)); end