Type Identification and Conversion
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. The reference material consulted while preparing these pages is listed in the section bibliography. |
Written against MATLAB R2026b. The sessions below were run in GNU Octave 11.3.0 (MATLAB code that Octave also accepts) and show Octave’s output; the MATLAB display layout may differ in spacing. Everything that needs tables, strings with +, datetime or other types Octave lacks is checked against the R2026b documentation and marked "not run here".
Every MATLAB value has a class, and many bugs are a value silently having a different class from the one the author imagined: an int8 that saturates, a char where a number was expected, a string in a place that wanted a cell. This page covers the two halves of that problem: finding out what a value is, and changing it into something else on purpose. The classes themselves are on Numeric Types and Floating Point, Strings and Character Arrays, Cell Arrays, Structures and Tables; declarative checks on function inputs are on Argument Validation.
Identifying a type: class and isa
class(x) returns the class name as a character vector. isa(x, name) is true if x is an instance of the class name or of a subclass of it, so it is the right test when inheritance is involved (see Inheritance and Abstract Classes).
isa also accepts three category names for numeric data:
| Category | True for |
|---|---|
|
|
|
|
|
|
The documentation table of fundamental classes lists single, double, the integer classes, logical, char, string, struct, cell, table, timetable and function_handle; categorical, datetime, duration and user-defined classes complete the picture. The half-precision class half is not part of base MATLAB: its reference pages belong to Fixed-Point Designer and GPU Coder (see Toolboxes and Add-On Products), and with those products installed a half value also counts as "numeric" and "float". It is not available in Octave and is not used in this section.
x = int8(5); s = 'abc'; c = {1,'a'}; st.a = 1;
class(x), class(s), class(c), class(st), class(@sin), class(1:3 > 2)
isa(x,'numeric'), isa(x,'integer'), isa(x,'float'), isa(single(1),'float'), isa(1,'float')
Octave 11.3.0 output, condensed here to the values printed, in the order the expressions appear (Octave prints each as ans = ...):
int8, char, cell, struct, function_handle, logical
1, 1, 0, 1, 1
Prefer the category form (isa(x,"numeric")) to a hand-written list of classes: it keeps working when a class such as the toolbox class half comes in. Note that the category names are not class names; class(x) never returns "numeric".
The is* family
A large family of functions answers a yes or no question about a value. The documentation topic Data Type Identification groups them by kind of data. The most used are in this table; each returns a scalar logical.
| Function | Question it answers |
|---|---|
|
numeric class (integers, floating point). |
|
floating-point class; integer class |
|
no imaginary part stored: |
|
the class is exactly that one |
|
a cell array in which every element is a character vector |
|
container and date types |
|
not in MATLAB. Use |
|
shape. |
|
at least one dimension is zero |
|
the existence of a named thing |
|
element-wise state; these return an array, not a scalar |
The shape and state functions are about the value, not the class, so they are often combined with a class check. Test the class first and the shape second, because a shape test on the wrong class can error.
isnumeric(true), isnumeric('a'), ischar('abc'), iscell({1}), isstruct(struct('a',1)), islogical(true)
isreal(3+0i), isreal(complex(3,0))
isscalar(5), isvector([1 2 3]), isrow([1 2 3]), iscolumn([1;2]), ismatrix(ones(2,3)), isempty([])
isfloat(int8(5)), isinteger(int8(5))
Octave 11.3.0 output, in order:
0, 0, 1, 1, 1, 1
1, 0
1, 1, 1, 1, 1, 1
0, 1
The isreal row shows a documented subtlety: 3+0i is simplified to a real 3 by the parser, but complex(3,0) keeps its imaginary part, and isreal reports storage, not value. Use all(imag(x(:)) == 0) to test the value. is_function_handle exists in Octave, so the output above does not tell you it is available in MATLAB; use isa(f,"function_handle") there.
Checking inputs: validateattributes and arguments
validateattributes(A, classes, attributes) checks that A belongs to one of the listed classes (or a subclass; categories such as "numeric" are accepted) and has all the listed attributes, such as "positive", "scalar", "integer", "vector", "nonempty", "finite", ">=" or "size". It returns nothing on success and throws an error otherwise. Longer forms add a function name, a variable name and an argument position so the error message points at the caller.
The documentation is explicit: input argument validation with arguments blocks is recommended over validateattributes (available since R2019b; see Argument Validation). validateattributes remains useful in code that must run on older releases, for checks inside a function body, and for validating values that do not come from the argument list.
try
validateattributes(-5, {'numeric'}, {'positive'});
catch err
disp(err.message)
end
validateattributes(5, {'numeric'}, {'positive','scalar'});
disp('ok')
Octave 11.3.0 output:
input must be positive
ok
Octave’s message is shorter than MATLAB’s, which names the variable and a message identifier; the wording and identifiers vary by release and are not run here for MATLAB.
Converting between numeric classes
A numeric class conversion is a function call with the name of the target class: double(x), single(x), int8(x), uint16(x), logical(x). Two rules matter.
-
Integer conversion rounds to the nearest integer, halves away from zero, and saturates.
int8(2.5)is3,int8(-2.5)is-3,int8(200)is127anduint8(-5)is0. MATLAB does not wrap around and does not warn. Usefloor,ceil,fixorroundfirst if you want a different rounding rule. -
Integer arithmetic saturates too.
uint8(200) + uint8(100)is255. Arithmetic between an integer and adoubleproduces the integer class (int8(5) * 2.5is anint8), and arithmetic between two different integer classes is an error.
int8(200), uint8(-5), int8(2.5), int8(3.5), int8(-2.5)
x = 3.99; int32(x), floor(x), fix(-3.99)
uint8(200)+uint8(100)
class(int8(5)*2.5), class(single(1)+1), class(int8(1)+true)
try, int8(1)+int16(1), catch e, disp(e.message), end
x = int8([100 120]); y = x*2
logical([2 0 -1])
Octave 11.3.0 output, in order:
127, 0, 3, 4, -3
4, 3, -3
255
int8, single, int8
binary operator '+' not implemented for 'int8 scalar' by 'int16 scalar' operations
y = 127 127
1 0 1
The mixed-integer error text above is Octave’s. MATLAB also raises an error for the same operation (message and identifier vary by release, not run here); convert one operand explicitly (int16(a) + b) to make the intended result type clear. logical follows the rule of Logical Type and Conditions: nonzero is true and NaN is an error.
Concatenation decides the class
Putting values of different classes in one array converts them to a common class; the rules are fixed but surprising.
| Combination | Resulting class |
|---|---|
integer with |
the integer class (the leftmost integer class if several) |
|
|
|
|
class(['a' 66]), class([int8(1) 2.7]), [int8(1) 2.7], class([single(1) 2])
Octave prints a warning for the char case ("implicit conversion from numeric to char"); the classes it reports are char, int8, single, with the second array shown as 1 3 (2.7 rounds to 3). MATLAB does not print that warning.
cast and typecast: two different operations
cast(x, "int8") converts the value like int8(x) does. typecast(x, "uint32") reinterprets the bits of x as another class without changing them, so the numeric values (and the number of elements) change.
cast(3.7,'int8'), class(cast(3.7,'int8'))
typecast(single(1),'uint32')
intmax('int8'), intmin('int8'), realmax('single')
Octave 11.3.0 output, in order: 4, int8, 1065353216 (the IEEE 754 bit pattern of single 1), 127, -128, 3.4028e+38.
Use intmax, intmin, realmax and flintmax instead of typing limits.
Numbers to text and text to numbers
Conversions between numbers and text are the most common in practice and the most error-prone.
| Task | Preferred form |
|---|---|
number to character vector, default format |
|
number to string |
|
number inside a message |
|
text to double, safely |
|
text to numeric, arbitrary expression |
|
characters to codes and back |
|
integer to digits |
|
matrix to MATLAB source text |
|
str2double is the function to use for data. It returns NaN instead of an error, so a missing or malformed field in a sensor log becomes a missing number that later code can detect. The documentation states what text may contain: digits, a comma used as a thousands separator, a decimal point, a leading sign, an exponent with e, and i or j for a complex unit. A comma cannot be a decimal separator and a period cannot be a thousands separator, so the European "21,5" is read as 215, which is a silent data error. Clean such text first (replace(txt, ",", ".")) when the source uses a decimal comma.
str2num is different in kind: it is implemented with eval, so it runs whatever MATLAB code the text contains. The documentation warns about this and says to use Evaluation="restricted" (basic math expressions only) or str2double for untrusted input. It also silently returns [] when the text does not parse, and is sensitive to spacing around + and -. Use it only for text that you wrote yourself, and see eval and Its Alternatives.
A heatflow sensor line, read as text and converted:
line = '2026-10-22 08:00:00,S1,21.5';
parts = strsplit(line, ',');
temp = str2double(parts{3})
class(temp)
bad = str2double('21,5')
r = str2double({'21.5','n/a','22.0'})
mat2str([1 2;3 4.5])
str2num('[1 2 3]*2')
Octave 11.3.0 output, in order: temp = 21.500, ans = double, bad = 215, r = 21.5000 NaN 22.0000, ans = [1 2;3 4.5], and ans = 2 4 6. The bad = 215 line is the decimal-comma trap described above; MATLAB documents the same comma rule for str2double. strsplit is available in current MATLAB, though split on a string is the modern form (see Strings and Character Arrays).
char, string and cellstr
Three text representations coexist (see Strings and Character Arrays): the character array, the string array (R2016b) and the cell array of character vectors. Converting among them:
-
string(c)turns a character vector or a cell array of character vectors into a string array;char(s)turns a string back into a character array (a string array with several elements gives a padded character matrix);cellstr(s)gives a cell array of character vectors. Not run here: Octave lacks thestringclass. -
Many functions accept either form. Function results usually keep the class of the input, so a
stringin gives astringout. Check withisstring,ischarandiscellstrat an API boundary, or convert once on entry withstring(x). -
stringalso converts dates and times: the documentation of Data Type Conversion states thatdatetimeanddurationare the recommended types for dates and times, converts them to text withstring, and converts text to them with thedatetimeanddurationfunctions.
Containers: cell, struct, table
The container conversions keep the data and change how it is stored and accessed.
| From | To | Function |
|---|---|---|
numeric array |
cell array of scalars |
|
cell array of same-class scalars |
numeric array |
|
cell array |
struct |
|
struct |
cell array |
|
struct |
table |
|
table |
struct |
|
table |
numeric array |
|
numeric array |
table |
|
cell array |
table |
|
table |
cell array |
|
text |
|
|
text |
|
|
num2cell([1 2 3])
cell2mat({1 2;3 4})
struct2cell(struct('a',1,'b','x'))
cell2struct({1;'x'},{'a';'b'},1)
Octave 11.3.0 output, in order: a 1-by-3 cell of 1, 2, 3; the 2-by-2 matrix 1 2 / 3 4; a 2-by-1 cell holding 1 and x; a structure with a = 1 and b = x. The table, datetime and categorical rows are checked against the documentation and are not run here.
Two cautions. table2array needs variables that can be concatenated (all numeric, say); a table with mixed types does not become one array. And cell2mat works only when the contents are the same class and have compatible sizes. Details are on Tables and Cell Arrays.
Conversion matrix
Read it as "from row to column"; each entry names the usual function. A dash means no direct conversion (go through another class).
| From / to | numeric | logical | char | string | cell | struct and table |
|---|---|---|---|---|---|---|
numeric |
|
|
|
|
|
|
logical |
|
|
|
|
|
|
char |
|
|
|
- |
||
string |
|
|
|
- |
||
cell |
|
|
|
|
||
struct |
- |
- |
- |
|
|
|
table |
|
- |
- |
|
|
Pitfalls
-
Integer saturation and rounding are silent. Convert to a wider class or
doublebefore arithmetic that can exceed the range. -
Mixed integer classes are an error; mixing an integer with
doublegives the integer class. -
A
charplus a number is a number, not text:'a' + 1is98. A string plus a number appends the number as text ("a" + 1is"a1", not run here). Build text withstring(n),num2str(n)orsprintf. -
str2doublewith a decimal comma gives a wrong number, notNaN. -
str2numruns code. Usestr2double, orEvaluation="restricted". -
isnumericis false forlogicalandchar, andisrealreports storage rather than value. -
classtells you the class only: a class check does not tell you the size, so combine it with shape checks orvalidateattributes.
Where older books differ
Older books present class, isa and the is* functions as the way to check inputs, and num2str as the way to build messages; both are still valid. They do not mention the arguments block (R2019b), which the documentation now recommends over validateattributes, the string class (R2016b) with its + concatenation, Evaluation="restricted" for str2num, or the numeric categories of isa as the recommended replacement for lists of class names. Some also use str2num for data parsing; str2double is safer. The conversion and saturation rules for integers have not changed.