问题
I need to pad zeros to specific locations in binary numbers. Looping the array form of a binary number such as dec2bin(43) and adding the zeros and adjusting the size sounds reinvention of the wheel.
How to pad zeros efficiently to binary numbers in Matlab?
Looping
positions=[1,3,6];
x=de2bi(43);
xx=flip(x);
kk=1;
for ii=1:length(x)+length(positions)
if isequal(positions(kk),xx(ii))
%Transfer the tail from ii by one index ahead,
%left out here because I think my method is bad!
x(ii)=0;
positions=positions+1; %Increase positions by one now due to one padding
kk=kk+1;
end
end
which feels too much reinvention: basically how to get 0 just before Y like from xxxxYabcd to xxxx0Yabcd where xxxxYabcd is a binary number?
Example
Input
101011, (1,3,6)
Output
100100110
1x010x11x (showing location of zeros clearer with x where zeros inserted)
回答1:
Although not much of a conceptual improvement, the following will do automatic re-indexing and assignment of the old values on a pre-padded matrix:
>> xx
xx =
1 0 1 0 1 1
nPads = length(positions);
nPadsShifts = 1:nPads;
y = ones(1, length(xx) + nPads); % re-indexing on the new array
y(positions + nPadsShifts) = 0; % padding values
y(y==1) = xx; % set original bit values
>> y
y =
1 0 0 1 0 0 1 1 0
回答2:
You can do it using just indexing. The positions of the zeros to be inserted in the extended vector are insertzeros+(1:length(insertzeros)) (where insertzeros is [1 3 6] in your example):
input = [1 0 1 0 1 1]; %// example data
insertzeros = [1 3 6]; %// example data
output = ones(1,length(input)+length(insertzeros));
output(insertzeros+(1:length(insertzeros))) = 0;
output(output==1) = input;
回答3:
Race begins! Mendo wins, gevang is a good second, thewaywewalk is the third and jaheruddin comes in fourth. The Shai's bitshifting is implemented in the shai function, unfortunately not yet getting it run faster.
Results
gevang :2.2e-05
thewaywewalk :5.6975e-05
mendo :2.2102e-05
jaheruddin :0.0001693
shai (poor hhh-implementation) 5.3288e-04
Warmed-up testing of the answers
function test_padding_zeros()
function myOutput=gevang(xx,positions)
nPads = length(positions);
nPadsShifts = 1:nPads;
myOutput = ones(1, length(xx) + nPads); % re-indexing on the new array
myOutput(positions + nPadsShifts) = 0; % padding values
myOutput(myOutput==1) = xx; % set original bit values
end
function myOutput=thewaywewalk(x,positions)
idx = numel(x):-1:1;
myOutput = num2cell(x);
myOutput(2,idx(positions)) = {0};
myOutput = [myOutput{:}];
end
function myOutput=jaheruddin(myInput,positions) % myInput can be a row vector or a matrix!
n = size(myInput,2)+numel(positions);
myOutput = false(size(myInput,1),n);
myOutput(:,setxor((1:length(positions)),1:n))=myInput;
end
function myOutput=mendo(myInput,positions)
myOutput = ones(1,length(myInput)+length(positions));
myOutput(positions+(1:length(positions))) = 0;
myOutput(myOutput==1) = myInput;
end
function out = bizarreBitShift( bNum, fromBit, shiftAmount )
% construct a mask
msk = uint32( (2^( fromBit - 1 ) )-1 );
shiftPart = bitand( uint32(bNum), bitcmp(msk) ); % bitcmp - complement of bits
staticPart = bitand( uint32(bNum), msk );
out = bitshift( shiftPart , shiftAmount );
out = bitor( out, staticPart );
end
function myOutput=shai(myInput,positions)
shiftAmount=1;
myOutput=sprintf('%d',myInput);
myOutput=bin2dec(myOutput);
k=0;
for ii=1:length(positions)
fromBit=positions(ii)+k;
myOutput=bizarreBitShift(myOutput, fromBit, shiftAmount);
k=k+1;
end
myOutput=ismember(dec2bin(myOutput),'1');
end
positions = [1 3 6]; %// example data
myInput = [1 0 1 0 1 1]; %// example data
ggevang=@() gevang(myInput,positions);
tthewaywewalk=@() thewaywewalk(myInput,positions);
mmendo=@() mendo(myInput,positions);
jjaheruddin=@() jaheruddin(myInput,positions);
sshai=@() shai(myInput,positions);
timeit(ggevang)
timeit(tthewaywewalk)
timeit(mmendo)
timeit(jjaheruddin)
timeit(sshai)
end
回答4:
If you are looking for efficiency it can never hurt to try various options. Here is another way to do it:
M = magic(5)>3; % Example matrix
positions = [2 3 6]; % Desired padding columns in resulting matrix
n = size(M,2)+numel(positions);
R = false(size(M,1),n);
R(:,setxor(positions,1:n))=M
回答5:
Shai provided here bitshifting solution for a single binary number. I use it below to pad the zeros, the solution can probably made far faster -- currently being one of the slowest solution (some unnecessary dec2bin) or about the same speed as Jaheruddin's solution.
function out = bizarreBitShift( bNum, fromBit, shiftAmount )
% construct a mask
msk = uint32( (2^( fromBit - 1 ) )-1 );
shiftPart = bitand( uint32(bNum), bitcmp(msk) ); % bitcmp - complement of bits
staticPart = bitand( uint32(bNum), msk );
out = bitshift( shiftPart , shiftAmount );
out = bitor( out, staticPart );
end
function myOutput=shai(myInput,positions)
shiftAmount=1;
myOutput=sprintf('%d',myInput);
myOutput=bin2dec(myOutput);
k=0;
for ii=1:length(positions)
fromBit=positions(ii)+k;
myOutput=bizarreBitShift(myOutput, fromBit, shiftAmount);
k=k+1;
end
myOutput=ismember(dec2bin(myOutput),'1');
end
positions = [1 3 6]; %// example data
myInput = [1 0 1 0 1 1]; %// example data
sshai=@() shai(myInput,positions);
timeit(sshai)
Timing
ans =
5.3288e-04
来源:https://stackoverflow.com/questions/20791048/command-to-pad-zeros-to-specific-locations-in-binary-numbers