[MUSIC] Hi, and welcome to Lesson Seven,
Data Types. MATLAB provides many ways of
storing numbers and variables, operating on them and printing them. We've seen lots of examples of numbers
being stored, operated on and printed. And these examples suggest that
these numbers are equivalent to the real numbers of mathematics. That's not the case. In mathematics,
real numbers can be infinitely large, and they have infinitely fine resolution, meaning that the difference between two
different numbers can be infinitely small. On the other hand computers
have a finite amount of memory. So there must be a limit on how large
a number represented in the memory can be. And there is. Also there's a limit on how
small the absolute value of a non-zero number can be. And if you think about it,
the finiteness of the memory means that a MATLAB variable can't
store an irrational number. So for example, the function pi returns
not pi, but only approximation of pi. And the square root function can return
only an approximation of the square root of two. Most important thing to learn
here is that the number of values that can be represented by
a variable in MATLAB is finite. And by the way that is true for
any computer language. This may seem like a pretty
significant limitation, but for the vast majority of problems that we
want to solve on the computer, the set of numbers that can be represented by
a variable is more than adequate, by far. The subject of this lesson is data types. And data types can help
handle this limitation. MATLAB supports many different data types. And they provide great flexibility
in dealing with numerical and non numerical data. A data type is sometimes
called simply a type. It is defined by a Set of values, and a Set of operations that can
be performed on those values. As we've seen, MATLAB allows a given function to be
called with different data types. There's a strict rule. All elements of a given array
must be of the same type. It's the array's elementary data type. In fact the type of a MATLAB array is
given by its number of dimensions, it's size in each dimension and
it's elementary data type. Well, let's play with
data types in MATLAB. Let's start by clearing the workspace. And let's create a new variable. Of course you do that by
assigning a value to it. So we got this variable x,
let's find out what its data type is. We do that with a function called Class. And it tells us that x is a type double. That's the default data type for
all numerical data in MATLAB. And that's not just for variables. It's for values too. For example, [SOUND] we just give it a
value without assigning it to a variable. MATLAB will still treat it as a double. By the way, why is the function
called class instead of type, since we're checking the types? Well, MATLAB reserves the name type for a command that prints out the contents
of a file, as in type the file. Let's get a little tricky here. Of course, you know that the square root
of minus one is an imaginary number, so you might expect the class to
say something about that but no, it just calls it a double. MATLAB supports complex numbers but
it doesn't distinguish among real, imaginary and complex numbers when
its classifying them into types. Let's make some more variables. Now let's look at a new function that
gives us even more information about them. It's called whos. First of all, whos prints out a list of the existing
variables in the current workspace. Simple. As you can see, x, y and z all have
double over here in the class column. As you'd expect. Over here the size column
shows the array dimensions. X is a one by one. Since all scalers are treated
as one by one arrays in MATLAB. Y is one by eight, as any well behaved
eight element row vector should be. And z is a three by four matrix. You may find the datatype for
ands surprising here. Char, well how did that happen? What's the value of ands anyway,
let's see. Hm. Double. Well is ands a double? No, remember this is the value
of ands we're seeing here. And that value is a string whose
characters are D-O-U-B-L-E. And, how did the value of
ands get to be a string? Well, it happened back here at this
command class square root of minus one. That was the last command we
issued in which we didn't assign the output to a variable. The class command returned the data
type of the output of the square root. And that happened to be a double. And returned that information as a string. Since we didn't assign this string
produced by the command class to a variable, MATLAB assigned it to ands. Of course, when we enter a string as,
for example, when we type the format string
of an fprintf statement, we have to put it in quotes to let MATLAB
know that it's not the name of a variable. When MATLAB prints a string,
it doesn't put it in quotes. As we'll see in a minute, a string is just
a row vector of values whose type is char. By the way, I pronounce C-H-A-R char. But char is also an equally acceptable
pronunciation, since it's short for character. When speaking of putting
strings in quotes, let's look at the type of
a string that we enter. There you go.
A char again, as expected. So how many types have we seen so far? We got the double and the char here, but we talked a great length
about one other type. That's right, logicals. You know the kind of value that
can only be true or false. So we've see the doubles,
the chars, and logicals. Now let's learn more about these types,
and introduce some new data types too. As we've seen, the default data
type in MATLAB is the double. That type uses floating
point representation. And what's that? Well you can think of
floating point representation as being like the scientific notation
that we talked about before. For example,
to represent the number 12.34, we can use the fact that 12.34 is equal to 1,234
times 10 raised to the minus 2 power. So we can store two integers,
1,234 and minus 2, to represent the non-integer 12.34. In floating point representation,
the 1,234 part is called the mantissa and the minus two part is called the exponent. MATLAB uses this floating point
representation for all doubles and it uses eight bytes of memory for
each one of them. Since there are eight bits in each byte,
we say that the double is a 64 bit number. The single is the only other floating
point type supported by MATLAB. The difference between the single and
the double is the length. The single has only 32 bits. By the way,
that's where the name double comes from. It occupies double
the space as the single. That extra space allows for
more digits, and so you'll sometimes hear
it called double precision. What if we know that
we need only integers. For example, sensor values that are read
in the computers are typically integers. And in image processing the color
values of pixels are always integers. Well MATLAB supports a number
of different integer data types. In fact, there are eight of them. There are four signed,
and four unsigned types. What does that mean, you ask? Well, if you don't need negative numbers,
you should used unsigned data types, because they represent only
non-negative integers, zero and higher. But if you do need negative numbers, or both negative and non-negative numbers,
then you need one of the signed types. The other important attribute
of integer data types is length. There are 8, 16, 32 and 64 bit variants of
integer types, both signed and unsigned. And they differ in the range
of numbers they can represent, with more bits giving a wider range. This table shows all of MATLAB's numerical
types and the ranges that they span. For example int8 which
is an eight bit integer, can cover the range between minus 128 and
plus 127. Well, why not plus 128, you ask? Well, the number of different values that
eight bits can form is 2 to the 8th power, which equals 256. So, it can only hold 256 values,
and we need to account for 0, too. The unsigned version, on the other hand, spans the integers from
0 all the way to 255. The table also shows the ranges
of the other integer data types. As you can see, a 64 bit integer can store
truly astronomical numbers, so it's very rare that any programmer needs integers
that are larger than int64 provides. At the bottom of the table,
you can see the range for the floating point data types, too. And the double range
is unimaginably large. But the singles and doubles can each
hold values outside their ranges, too. There are two of these
out of range values. The first is I-N-F, or inf, for infinity. Inf most commonly comes up when we
accidentally divide a nonzero number by zero, but it signifies the result
of any expression that gives a number greater than the largest
value that can fit in a double. You can guess what minus inf means. The second out of range
value that a single and double can have is in N-A-N or
NaN, for not a number. NaN signifies the result of an expression
that gives an invalid value, for example 0 divided by 0. So that's a look at the ranges for these types, now let's look at some
functions that deal with them. Here are a couple of useful built-in
functions for checking datatypes. We've seen the class function before,
it returns the name of its argument type. The isa function is new, it returns
true or false depending on whether the first argument has the data type whose
name is given in the second argument. The intmax and
intmin functions give the maximums and the minimums of the integer types. And realmax and realmin do the same
thing for the floating point types. We'll try them out in a minute. In addition to the functions for checking types, there's a set of
functions that do conversions among them. The need to convert a value from one data
type to another comes up from time to time and there are built-in functions
whose names are the same as the desired types to be produced by the conversion. We'll see these functions
in action in just a bit. Of course, what we do most often
with values in MATLAB is arithmetic, and there are rules for
arithmetic that depend on types. First, all arithmetic operations
have no problem accepting two operands of the same type, and
the result is always a value of that type. The MATLAB also allows some mixing of
data types in arithmetic expressions. It's called mixed-mode arithmetic,
and there are many rules and restrictions on what's allowed and
on the type of the result. These rules can be a bit complicated and
somewhat cumbersome, so we'll skip them here. But if you need to work with
mixed-mode arithmetic in your programs, the textbook explains the rules in detail. And finally, some good news. Relational operators work with any mixture
of numerical data types just fine. And not surprisingly, the result
always has the same type, logical. Now, let's play with numerical
types in MATLAB some more. First, let's just create a few numerical
variables with types other than doubles. A way to do that is to use
the built-in functions with the name of the given
data types that we need. For example, we just converted the double 98.76 into a single and
put it in x. And we just converted the double minus 16 into an int8 and put that in n. And we put a u int16 into m. Let's see what we've got here. There's our three variables,
there's their three types, and their sizes are all one by
one because they're all scalers. That works smoothly. But what if we try to assign a number
that doesn't fit in the given type. Let's look at some examples of that. What's happening here as you can probably
see is that the conversion function is producing the number that's closest to
the input value that can be represented in the given data type. Here we're dealing with
the uint8 data type, and it can hold the integers from 0 to 255. So 500 doesn't fit. It's bigger than 255, but
255 is the biggest number so it's as close to 500 as you can get. 256 is just a hair too big,
so we get 255 again. Here's minus 1, well an unsigned int can't
hold a negative number, so we get 0. So what's happening here exactly is, we start with this minus 1,
which is a double. Since any number you just type in
the MATLAB is a double by default. It's passed as input to uint8. Uint8 then converts that
minus 1 to the nearest 8 bit integer possible which happens to be 0. The function then returned
that value As a U Int 8 type, so we've got a U int 8 zero
coming out of U int 8. Then MatLab assigned that value to K, so K now has the U int 8 data type and
its value is zero. So let's look at K. It's zero, let's look at its type. U Int 8. This changing of an out of range
value to the value at the closest end of the range is sometimes called
clipping, because the operation clips off the excess of the value so
it'll just fit into that range. Here 500 was clipped to 255, and
minus one was clipped to zero. Matlab's assumption here is that
you know what you're doing. You explicitly asked it to convert a big
number to a type that it can't hold or a negative number to a type that
can only hold positive numbers. So rather than throwing an ugly
red error message at you and stopping your program in its tracks, it silently clips the big number down to
size or the negative number up to a zero. So in this case, now, k is equal to zero,
and it's type is U Int 8. But you have to be careful here. Look what happens if we decide to increase
K to some other value that fits inside the range of its type, you know, U Int 8. Say two. Okay it's now two and
let's just check its type. Well its type is now double. The moment we assigned 2 to k,
its data type changed. The number 2 is a double by default,
so when we assigned it to k, k ceased to exist as a U Int 8. Became a double. It's really quite logical. If we now assigned it a string, say, you wouldn't expect K to
remain a double, would you? And you'd be right. K didn't remain a double. It became a char. This illustrates a rule in MatLab. When a variable is assigned a value and new type,
the variable takes on the new type. Many other languages work differently. A variable is declared
to be of a given type. And it keeps that type. And if you were to assign a value of type
char to K after it's been declared to be a double, then either an error would occur
or an invisible conversion would take place right there on the spot during the
assignment statement from double to char, with the same sort of clipping happening. One approach is different from the other. Not better, just different. They each have their pros and cons, but once you know what the rules
are it's all quite logical. Boring, but logical. And to keep with this theme,
you know the boring theme, I'll show you how you can check the ranges
of the types you want to use so you'll know when clipping
is going to happen. There are four built-in functions
that we can use to do that, and here's some examples of them in action. Let me clear this screen first. [SOUND]. Bet you wish you could type that fast. We saw these same values in that
table a little earlier of course. It's pretty straightforward stuff. But it can be important when you're
working with very large arrays of numbers whose range is small
because of the application such as image processing for example. They don't have room to
store 64 bit doubles, so maybe you'll want to use eight bit or
16 bit or 32 bit integers. [MUSIC] Then this stuff won't be boring anymore. Wait, who am I kidding? This stuff will always be boring,
but at least it'll be useful. [MUSIC] [APPLAUSE]