No BSD License  

Highlights from
Canonical Signed Digits

from Canonical Signed Digits by Patrick Moran
Generates a CSD representation of a floating point number.

[digits,pos,neg,err]=csdigit(num,range,resolution)
function [digits,pos,neg,err]=csdigit(num,range,resolution)
% Returns the canonical signed digit representation of the input number.
% Useful for simple DSP implementations of multipliers.
%    [digits,pos,neg,err]=csdigit(num,range,resolution)
%
% example csdigit(23) returns +0-00-.
%         Where +0-00-. is a representation of +1 in 2^5, -1 in 2^3 and -1 in 2^0 positions.
%         i.e. 23 = 32 - 8 -1
%
% example [a,p,n]=csdigit(23.5,6,2) returns
%            a = +0-000.-0
%            p=32
%            n=8.5
%            23.5 = 32 - 8 -.5
%
% num           = input number (decimal)
% range         = maximum digits to the left of the decimal point
% resolution    = digits to the right of decimal point
% for example
%    csdigit(.25,2,2) represents xx.xx binary
%    csdigit(.25,0,4) represents .xxxx binary
% Note: An error is generated if num does not fit inside the representation.
%       is truncated to the specified resolution.
% Note: A warning message is generated if num doesn't fit in the precision
%       specified. The returned value is truncated.
% Note: The range is not used except for a check for overflow and to add
%       leading zeros.
%
% Patrick J. Moran
% AirSprite Technologies Inc.

% Copyright 2006, Patrick J. Moran for AirSprite Technologies Inc.
% Redistribution and use in source and binary forms, with or without modification, 
% are permitted provided that the following conditions are met:
% 
%    1. Redistributions of source code must retain the above copyright notice.
%    2. Any derivative of this work must credit the author, and must be made available to everyone.
%    3. The name of the author may not be used to endorse or promote products derived 
%       from this software without specific prior written permission.
%
% THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 
% INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
% PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 
% INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
% LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
% OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 
% WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if nargin<1
    help csdigit;
    return
end
if nargin<2
    range=ceil(log(abs(num))/log(2))+1;
end
if nargin<3
    resolution=0;
end
targetNum=num;
num=abs(num)/(2^(-resolution));
if num~=floor(num)
    if floor(num)==0
        error('Insufficient precision to represent this number!')
    else
        warning('Some precision has been lost. Returned value is truncated!')
    end
end
num=floor(num);
if num>(2^(range+resolution))
    error('Input number is too large for the requested bit representation.');
end
binNum=dec2bin(num,range+resolution);
digits=('0'+0)*ones(size(binNum));
%allZeros=allZeros;
onesLoc=findstr(binNum,'1');
if ~isempty(onesLoc)
    onesRun=find(diff(onesLoc)==1);
    while ~isempty(onesRun)
        onesPointer=find(diff(onesLoc)==1)+1;
        addIn=onesLoc(onesPointer(end));
        adder=('0'+0)*ones(size(binNum));
        adder(addIn)=('1'+0);
        %keep track of the additional digits
        digits(addIn)=('-'+0);
        binAdder=char(adder);
        binNum=dec2bin(bin2dec(binNum)+bin2dec(binAdder),range+resolution);
        onesLoc=findstr(binNum,'1');
        onesRun=find(diff(onesLoc)==1);
        if length(binNum)>length(digits)
            digits=['0'+0,digits]; % add any additional leading zero
        end
    end
end
pos=bin2dec(binNum)*2^(-resolution);
negLoc=find(digits==('-'+0));
neg=('0'+0)*ones(size(binNum));
neg(negLoc)='1'+0;
neg=bin2dec(char(neg))*2^(-resolution);
digits(onesLoc)='+'+0;
if (length(digits)-resolution)>range
    warning('Number overflowed for this CSD representation')
end
if length(digits)<resolution
    digits=[digits,('0'+0)*ones(1,resolution-length(digits))];
end
digits=char([digits(1:length(digits)-resolution),'.'+0,digits(length(digits)-resolution+1:end)]);
if targetNum<0 % flip representation if negative
    ntemp=neg;
    neg=pos;
    pos=ntemp;
    digits=strrep(digits,'+','p');
    digits=strrep(digits,'-','+');
    digits=strrep(digits,'p','-');
end
%digits=char(digits);
err=targetNum-(pos-neg);

Contact us at files@mathworks.com