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

"numeric"

double, single and all eight integer classes (not logical, not char)

"float"

double and single

"integer"

int8, int16, int32, int64, uint8, uint16, uint32, uint64

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

isnumeric(x)

numeric class (integers, floating point). false for logical and char

isfloat(x), isinteger(x)

floating-point class; integer class

isreal(x)

no imaginary part stored: isreal(complex(3,0)) is false even though the imaginary part is zero

islogical(x), ischar(x), isstring(x)

the class is exactly that one

iscellstr(x)

a cell array in which every element is a character vector

iscell(x), isstruct(x), istable(x), istimetable(x), iscategorical(x), isdatetime(x)

container and date types

is_function_handle(x)

not in MATLAB. Use isa(x,"function_handle")

isscalar(x), isvector(x), isrow(x), iscolumn(x), ismatrix(x)

shape. ismatrix is true for any 2-D array (including scalars and vectors)

isempty(x)

at least one dimension is zero

isfield(s,name), isprop(obj,name), isvarname(txt), isfile(p), isfolder(p)

the existence of a named thing

isnan(x), isinf(x), isfinite(x), ismissing(x)

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) is 3, int8(-2.5) is -3, int8(200) is 127 and uint8(-5) is 0. MATLAB does not wrap around and does not warn. Use floor, ceil, fix or round first if you want a different rounding rule.

  • Integer arithmetic saturates too. uint8(200) + uint8(100) is 255. Arithmetic between an integer and a double produces the integer class (int8(5) * 2.5 is an int8), 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 double, single or logical

the integer class (the leftmost integer class if several)

single with double

single

char with any number

char, the numbers becoming character codes

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

num2str(x); num2str(x, 8) for a number of significant digits; num2str(x, "%8.3f") for a format

number to string

string(x), which gives a string scalar for a scalar, an array of strings for an array

number inside a message

"T = " + string(21.5) or sprintf("T = %.1f", 21.5)

text to double, safely

str2double(txt): returns NaN for text that is not a number; accepts a character vector, a cell array of character vectors or a string array

text to numeric, arbitrary expression

str2num(txt): uses eval; avoid

characters to codes and back

double("A") is 65; char(72) is "H"

integer to digits

int2str(2.7) rounds to 3

matrix to MATLAB source text

mat2str([1 2;3 4.5]) gives [1 2;3 4.5]

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 the string class.

  • Many functions accept either form. Function results usually keep the class of the input, so a string in gives a string out. Check with isstring, ischar and iscellstr at an API boundary, or convert once on entry with string(x).

  • string also converts dates and times: the documentation of Data Type Conversion states that datetime and duration are the recommended types for dates and times, converts them to text with string, and converts text to them with the datetime and duration functions.

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

num2cell(A)

cell array of same-class scalars

numeric array

cell2mat© (also joins equal-sized blocks)

cell array

struct

cell2struct(C, fields, dim)

struct

cell array

struct2cell(S)

struct

table

struct2table(S)

table

struct

table2struct(T)

table

numeric array

table2array(T)

numeric array

table

array2table(A)

cell array

table

cell2table©

table

cell array

table2cell(T)

text

categorical

categorical(txt)

text

datetime or duration

datetime(txt), duration(txt)

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

double, int8 and the others

logical

char (character codes), num2str

string

num2cell

array2table

logical

double

char

string

num2cell

array2table

char

str2double, double (codes)

string

cellstr

-

string

str2double, double

char

cellstr

-

cell

cell2mat

char

string

cell2struct, cell2table

struct

-

-

-

struct2cell

struct2table

table

table2array

-

-

table2cell

table2struct

Pitfalls

  • Integer saturation and rounding are silent. Convert to a wider class or double before arithmetic that can exceed the range.

  • Mixed integer classes are an error; mixing an integer with double gives the integer class.

  • A char plus a number is a number, not text: 'a' + 1 is 98. A string plus a number appends the number as text ("a" + 1 is "a1", not run here). Build text with string(n), num2str(n) or sprintf.

  • str2double with a decimal comma gives a wrong number, not NaN.

  • str2num runs code. Use str2double, or Evaluation="restricted".

  • isnumeric is false for logical and char, and isreal reports storage rather than value.

  • class tells you the class only: a class check does not tell you the size, so combine it with shape checks or validateattributes.

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.