home *** CD-ROM | disk | FTP | other *** search
- function x = str2num(s)
- %STR2NUM String to number conversion.
- % X = STR2NUM(S) converts the string S, which should be an
- % ASCII character representation of a numeric value, to MATLAB's
- % numeric representation. The string may contain digits, a decimal
- % point, a leading + or - sign, an 'e' preceeding a power of 10 scale
- % factor, and an 'i' for a complex unit.
- % If the string S does not represent a valid number, STR2NUM(S)
- % returns the empty matrix.
- %
- % See also NUM2STR, HEX2NUM.
-
- % Copyright (c) 1984-93 by The MathWorks, Inc.
-
- if ~isstr(s) | size(s,1) > 1
- error('Requires string argument.')
- end
- % remove trailing and leading blanks
- s = deblank(fliplr(deblank(fliplr(s))));
- if isempty(s),
- x = [];
- return
- end
- % find remaining blanks
- ib = find(s == ' ');
- if ~isempty(ib)
- ib1 = diff(ib);
- if isempty(ib1) % only 1 blank - make sure it's before or after a sign
- if ~any(s([ib-1 ib+1]) == '+' | s([ib-1 ib+1]) == '-')
- x = [];
- return
- end
- else % look for contiguous blocks of 1s, at most 2 of them - i.e., at most 1 non-1
- ib11 = find(ib1 ~= 1);
- if length(ib11) > 1
- x = [];
- return
- elseif length(ib11) == 1 % make sure the character in between is a plus or a minus
- ipm = any(s([ib-1 ib+1]) == '+' | s([ib-1 ib+1]) == '-');
- if ~ipm
- x = []
- return
- end
- end
- end
- end
- % now squeeze out remaining blanks
- s(s==' ') = [];
- % check for unwanted characters
- if ~all (((s < 58) & (s > 47)) | (s == 'i') | (s == 'j') | ...
- (s == '.') | (s == 'e') | (s == 'E') | (s == '+') | (s == '-') | (s == '.'))
- x = [];
- return
- end
- % Peel off possible imaginary part.
- % it better be the last thing, if it exists at all.
- % possible complex number - try to convert.
- ind = find(s == 'j');
- if ~isempty(ind)
- s(ind) = 'i';
- end
- ind = find(s == 'i');
- if ~isempty(ind)
- if length(ind) > 1
- x = [];
- return
- end
- if ind ~= length(s)
- x = [];
- return
- end
- if ind == 1
- s = ['+0+1i'];
- end
- % make sure there is a real part and separate real and imaginary parts with
- % a space for sscanf.
- % to help, if there's no leading sign, put in a plus
- if s(1) ~= '+' & s(1) ~= '-'
- s = ['+' s];
- end
- % look for character before + and - signs; the real and imaginary parts are
- % separated with + or - signs and optional spaces, but before the +/-, there
- % must be a number
- sind = find(s=='+' | s=='-');
- if isempty(sind) % number had better be purely imaginary
- s = ['+0+' s];
- else
- % ignore leading sign for now
- sind(1) = [];
- % find potential digits or periods preceding a sign (otherwise it's e or malformed)
- digits = s(sind-1);
- dig_ind = find(digits == '.' | (abs(digits) >= 48 & abs(digits) <= 57));
- if length(dig_ind) ~= 1
- x = [];
- return
- end
- s = [s(1:sind(dig_ind)-1) ' ' s(sind(dig_ind):length(s))];
- end
- % pulled off final i, now read 2 parts
- % check to make sure there's a digit just before this
- s(length(s)) = [];
- last = s(length(s));
- if abs(last) < 48 | abs(last) > 57
- if last ~= '.'
- s = [s '1'];
- end
- end
- [a,b,c] = sscanf([s ' '],'%g',2);
- if isempty(c)
- x = a(1)+i*a(2);
- else
- x = [];
- end
- return
- else
- % check to make sure that there is only one number in the string if
- % there is no 'e' or 'E' in it
- if ~any(s=='e' | s == 'E'),
- [a,b,c] = sscanf([s ' '],'%g',2);
- if b > 1
- x = [];
- return;
- end
- end
- end
-
- % make sure that the string does not end in an 'e' or an 'E'
- if (s(length(s)) == 'e') | (s(length(s)) == 'E'),
- x = [];
- return
- end
-
- % possible real number - try to convert.
- [a,b,c] = sscanf([s ' '],'%g',1);
- if isempty(c)
- x = a;
- else
- x = [];
- end
-