问题描述
需要MATLAB
/Octave
dec2base
具有独立位/位数计算算法的功能函数(在整数逻辑中,没有除法,使用模算术)。
也很高兴:
- 匿名函数
注意! 标量只能使用一次浮点逻辑和除法来定义转换后的数字数组中的最大位数:
ceil( log2(max(dec(:)))/log2(base)) )
附言
- 针对简化的
dec2bin
案例列出的解决方案 here。 - 这篇博文中提供的
bitget
的解决方案:Matlab/Octave bitget function for any base
解决方法
-
在
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
-
仅在
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,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 ...,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,0) % behaves as dec2base(x,base) without converting/mapping to string/char format ans = 1 9 1 10 1 11 1 12 de2bs(x,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 Operations 支持的 MatLab 版本):
function dig = de2bs(dec,isoutputnumerical,pos)
% de2bs(D)
% de2bs(D,BASE)
% de2bs(D,BASE,ISOUTPUTNUMERICAL)
% de2bs(D,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,ISOUTPUTNUMERICAL)
% By default,ISOUTPUTNUMERICAL is false
%
% de2bs([123,321],0)
% ans = 07B
% 141
%
% de2bs([123,1)
% ans = 0 7 11
% 1 4 1
%
%
% de2bs(D,POS)
% POS - optional array of digits positions (like in bitget function)
% By default pos = (ceil( log2(max(dec(:)))/log2(base)) ):-1:1 )
%
% dde2bs([123,3,0)
% ans = 011120
% 102220
%
% de2bs([123,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,1]),3);
if isoutputnumerical == false dig = reshape(symbols(dig+1),size(dig)); end