WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000 00:00:05.511 --> 00:00:08.510 DOUG LLYOYD: So hexadecimal numbers, as if we needed another base number 00:00:08.510 --> 00:00:09.970 scheme right? 00:00:09.970 --> 00:00:13.000 Well, most Western cultures, as you probably are familiar, 00:00:13.000 --> 00:00:16.560 use the decimal system-- base 10, to represent numeric data. 00:00:16.560 --> 00:00:20.520 We have the digits 0, 1, 2, 3, 5, 6, 7,8,9. 00:00:20.520 --> 00:00:23.890 And if we need to represent values higher than nine, 00:00:23.890 --> 00:00:26.800 we can combine those digits using the notion of place value. 00:00:26.800 --> 00:00:30.115 So for 10, we have a 1 digit followed by a 0 digit 00:00:30.115 --> 00:00:32.240 and we intuitively understand that what we're doing 00:00:32.240 --> 00:00:35.500 there is we're multiplying the first 1 by 10, 00:00:35.500 --> 00:00:37.689 and then adding 0 for a total of 10. 00:00:37.689 --> 00:00:40.480 Computers do something pretty similar, as you're probably familiar, 00:00:40.480 --> 00:00:42.409 with the binary system-- base 2. 00:00:42.409 --> 00:00:44.700 The difference there being that there are only 2 digits 00:00:44.700 --> 00:00:46.770 to work with-- 0 and 1. 00:00:46.770 --> 00:00:49.033 And so our place values, instead of being one, 00:00:49.033 --> 00:00:52.600 ten, hundred, thousand, as they would be in the decimal system, 00:00:52.600 --> 00:00:57.690 are one, two, four, eight, and so on. 00:00:57.690 --> 00:01:00.842 Here's the thing though, those 0's and 1's, especially 00:01:00.842 --> 00:01:03.800 if we're being computer scientists and we're doing a lot of programming 00:01:03.800 --> 00:01:06.924 or working with computers, were going to be seeing a lot of binary numbers. 00:01:06.924 --> 00:01:11.660 And those 0's and 1's in large chains can be very difficult to parse. 00:01:11.660 --> 00:01:16.610 We can't just look at a string of 0's and 1's and necessarily know 00:01:16.610 --> 00:01:17.810 exactly what it is. 00:01:17.810 --> 00:01:21.980 But it's still useful to be able express data in the same way 00:01:21.980 --> 00:01:23.480 that a computer does. 00:01:23.480 --> 00:01:26.580 We have this notion of the hexadecimal system, which is 00:01:26.580 --> 00:01:29.840 base 16, instead of base 10 or base 2. 00:01:29.840 --> 00:01:34.420 Which means that we have 16 digits to work with instead of 10 or 2. 00:01:34.420 --> 00:01:37.180 And it's a much more concise way to express 00:01:37.180 --> 00:01:41.210 binary information on a computer system, it's much more human understandable. 00:01:41.210 --> 00:01:43.520 So we have the digits 0 through 9, and then 00:01:43.520 --> 00:01:49.480 we also have these extra six digits-- a, b, c, d, e, and f, which represent 10, 00:01:49.480 --> 00:01:56.050 our notion of 10, 11, 12, 13, 14 and 15, in decimal. 00:01:56.050 --> 00:01:59.787 Sometimes, by the way, you'll also see these a through f's as capital A 00:01:59.787 --> 00:02:01.620 through F, which is the way I tend to do it. 00:02:01.620 --> 00:02:04.560 It's just my preferred style, but either is fine, 00:02:04.560 --> 00:02:07.870 they both represent pretty much the same thing. 00:02:07.870 --> 00:02:09.090 >> So why is hexadecimal cool? 00:02:09.090 --> 00:02:11.580 Why do we need to use this other additional base? 00:02:11.580 --> 00:02:14.310 We already have 2 and 10, why do we need 16? 00:02:14.310 --> 00:02:21.650 Well 16 is a power of 2, and so each hexadecimal digit, 0 through f, 00:02:21.650 --> 00:02:25.440 corresponds to a unique ordering, or unique arrangement 00:02:25.440 --> 00:02:29.060 of 4 binary digits, 4 bits. 00:02:29.060 --> 00:02:34.570 And so in that sense, we can express very long, complex, binary numbers 00:02:34.570 --> 00:02:36.440 in hexadecimal in a much more concise way, 00:02:36.440 --> 00:02:41.080 without losing information or having to do particularly cumbersome conversions 00:02:41.080 --> 00:02:42.480 on those numbers. 00:02:42.480 --> 00:02:44.880 >> So, as I just said, each hexadecimal digit 00:02:44.880 --> 00:02:48.630 corresponds to a unique arrangement of 4 binary digits. 00:02:48.630 --> 00:02:53.670 So the binary string 0000 corresponds to hexadecimal digit 0. 00:02:53.670 --> 00:03:00.340 0110 corresponds to hexadecimal digit 6. 00:03:00.340 --> 00:03:05.225 And 1111 corresponds to hexadecimal digit f. 00:03:05.225 --> 00:03:07.100 If you're looking at this chart, particularly 00:03:07.100 --> 00:03:09.099 if you're looking at the left side of the chart, 00:03:09.099 --> 00:03:11.970 you can already see there's a bit of an ambiguity problem here. 00:03:11.970 --> 00:03:15.229 Decimal 0 is pretty much indistinguishable from hexadecimal 0, 00:03:15.229 --> 00:03:18.020 other than the fact that it's under a column that says hexadecimal. 00:03:18.020 --> 00:03:22.130 >> But we probably won't always have that column there. 00:03:22.130 --> 00:03:25.420 Generally when we are expressing numbers into hexadecimal notation 00:03:25.420 --> 00:03:28.130 to clearly distinguish them from decimal notation, 00:03:28.130 --> 00:03:31.860 we usually prefix them with the prefix 0x. 00:03:31.860 --> 00:03:35.990 0x means nothing in reality, it's just a clue to us as humans 00:03:35.990 --> 00:03:39.190 that what we're about to see, or about to start parsing, 00:03:39.190 --> 00:03:40.750 is a hexadecimal number. 00:03:40.750 --> 00:03:45.590 Obviously for the higher digits a, b, c, d, and f, which correspond to 10-15 00:03:45.590 --> 00:03:48.840 it's pretty unambiguous that's that's a hexadecimal number. 00:03:48.840 --> 00:03:51.620 And in fact, any hexadecimal number that has letters in it, 00:03:51.620 --> 00:03:54.642 is probably pretty obvious as a hexadecimal number. 00:03:54.642 --> 00:03:56.350 But, still, for the sake of clarity, it's 00:03:56.350 --> 00:03:58.290 always a good idea to prefix every time you 00:03:58.290 --> 00:04:01.835 refer to a digit as a hexadecimal number by prefixing a 0x. 00:04:04.370 --> 00:04:06.810 >> So, binary, as we said, has place values. 00:04:06.810 --> 00:04:10.040 There's the ones place, a twos place, a fours place, and an eights place. 00:04:10.040 --> 00:04:13.640 And decimal also has place values, the ones, tens, hundreds, and thousands 00:04:13.640 --> 00:04:15.910 that we all may recall from grade school. 00:04:15.910 --> 00:04:18.050 And hexadecimal is no exception here, really. 00:04:18.050 --> 00:04:22.660 It also has place values but instead of being powers of 2 or powers of 10, 00:04:22.660 --> 00:04:25.050 they're powers of 16. 00:04:25.050 --> 00:04:29.410 >> So we see a number like this we pretty clearly know it's 397, right? 00:04:29.410 --> 00:04:33.420 Well if we see a number like this, we know this isn't 397 anymore. 00:04:33.420 --> 00:04:36.730 This is the hexadecimal number three-nine-seven. 00:04:36.730 --> 00:04:39.680 It's not 397, it means something different, 00:04:39.680 --> 00:04:44.180 because we're using powers of 16 as all of our place values instead of powers 00:04:44.180 --> 00:04:45.560 of 10. 00:04:45.560 --> 00:04:50.570 In fact, the place values here would be the ones place, the sixteens place, 00:04:50.570 --> 00:04:55.080 and the two-hundred-fifty-sixes place, which correspond to our idea of a ones 00:04:55.080 --> 00:04:59.180 place, tens place, and a hundreds place, if the number was 397. 00:04:59.180 --> 00:05:03.620 But since it's 0x 397, we have a ones place, sixteens place, 00:05:03.620 --> 00:05:05.780 and a two-hundred-fifty-sixes place. 00:05:05.780 --> 00:05:09.460 Or, a 16 to the 0 place, which is 1. 00:05:09.460 --> 00:05:12.420 A 16 to the first power place, 16. 00:05:12.420 --> 00:05:17.080 A 16 squared place, 256, and so on, and so on, and so on. 00:05:17.080 --> 00:05:24.400 So this number is really 3 times 16 squared, plus 9 times 16, plus 7. 00:05:24.400 --> 00:05:28.980 I didn't do the math here, but it's not 397, it's much, much larger than that. 00:05:28.980 --> 00:05:34.050 >> Similarly, we could have 0x adc, well that's a times 16 squared. 00:05:34.050 --> 00:05:38.220 Or if we translate that to our notion of decimal numbers, that's 10 times 00:05:38.220 --> 00:05:44.160 16 squared, plus d times 16, or plus 13 times 16. 00:05:44.160 --> 00:05:47.410 And don't worry if you haven't memorized that d is 13, or anything like that, 00:05:47.410 --> 00:05:49.201 there's not too many of these letter digits 00:05:49.201 --> 00:05:52.820 and it'll become intuitive pretty quickly. 00:05:52.820 --> 00:05:59.800 So again this is 10 times 16 squared, plus 13 times 16, plus 12 times 1. 00:05:59.800 --> 00:06:03.640 So 0x adc. 00:06:03.640 --> 00:06:07.750 >> So, as I said, every group of 4 binary digits 00:06:07.750 --> 00:06:10.000 corresponds to a single hexadecimal digit, 00:06:10.000 --> 00:06:12.570 and so it's actually really easy to change back and forth 00:06:12.570 --> 00:06:14.690 between hex and binary. 00:06:14.690 --> 00:06:18.310 If you have this long string of binary digits, all you need to do 00:06:18.310 --> 00:06:21.320 is start grouping them right to left as groups of 4. 00:06:21.320 --> 00:06:26.550 And then you can consolidate them into hexadecimal numbers, 00:06:26.550 --> 00:06:30.910 severely limiting the number of digits you have to process mentally. 00:06:30.910 --> 00:06:33.680 Instead of 32 0's and 1's, as we'll see in a second, 00:06:33.680 --> 00:06:37.630 you might be able to get it down to just 8 hexadecimal digits, a lot 00:06:37.630 --> 00:06:39.200 more concise. 00:06:39.200 --> 00:06:43.500 >> The charts a few slides back will help you to figure out this mapping, 00:06:43.500 --> 00:06:45.660 although, again you'll memorize it pretty quickly. 00:06:45.660 --> 00:06:47.320 We'll go through an example right now. 00:06:47.320 --> 00:06:51.507 So if we have a number like this, this really large binary number, 00:06:51.507 --> 00:06:53.340 or what appears to be a large binary number. 00:06:53.340 --> 00:06:56.260 And the reason I say that, it's just so-- it's a behemoth, right? 00:06:56.260 --> 00:06:58.959 There's so many 0's and 1's there. 00:06:58.959 --> 00:07:01.000 But we probably don't really have a sense of what 00:07:01.000 --> 00:07:02.870 the magnitude of this number really is. 00:07:02.870 --> 00:07:06.150 We don't have any idea what it would correspond to a decimal. 00:07:06.150 --> 00:07:09.744 And in fact we won't even see what it corresponds to in decimal right now. 00:07:09.744 --> 00:07:11.660 We might be able to express this in a way that 00:07:11.660 --> 00:07:15.640 would give us some more information about just how big this number is. 00:07:15.640 --> 00:07:17.270 >> So let's go to that conversion process. 00:07:17.270 --> 00:07:19.311 The first thing we need to do is we want to group 00:07:19.311 --> 00:07:23.050 these digits out into groups of 4, starting from the right 00:07:23.050 --> 00:07:24.120 and working to the left. 00:07:24.120 --> 00:07:27.260 There happen to be 32 digits here, which means we have 00:07:27.260 --> 00:07:33.210 a nice clean break of 8 groups of 4. 00:07:33.210 --> 00:07:36.200 Remember that each group of 4 here, uniquely corresponds 00:07:36.200 --> 00:07:37.760 to a hexadecimal digit. 00:07:37.760 --> 00:07:42.080 So we'll start again building our number from the right, and working left. 00:07:42.080 --> 00:07:44.890 Well what's 1101? 00:07:44.890 --> 00:07:49.220 Well we do the math out in our head, we have 1 in the eights place, a 1 00:07:49.220 --> 00:07:54.310 in the fours place, a 0 in the twos place, and a 1 in the ones place. 00:07:54.310 --> 00:07:58.820 That's 8 plus 4 plus 1, which we would know as 13. 00:07:58.820 --> 00:08:02.400 But we probably wouldn't write 13 out, because we're working with hexadecimal. 00:08:02.400 --> 00:08:07.982 We need to convert it to the hexadecimal equivalent of 13, which is d. 00:08:07.982 --> 00:08:12.940 >> 0011, well that's a 0 in the eights place, a 0 in fours place, 00:08:12.940 --> 00:08:15.190 a 1 in the twos place, and a 1 in the ones place. 00:08:15.190 --> 00:08:16.880 That's 3. 00:08:16.880 --> 00:08:20.180 I mean keep doing this again, we have here 9. 00:08:20.180 --> 00:08:23.850 And then 11, but that's b, recall. 00:08:23.850 --> 00:08:30.570 2, 10-- or a-- 6, and 4. 00:08:30.570 --> 00:08:34.669 And so that very large string of 0's and 1's of the top 00:08:34.669 --> 00:08:38.549 is more concisely expressed in hexadecimal as 0x 46a2b93d. 00:08:42.309 --> 00:08:45.870 >> Well, OK, we've learned a new cool skill, what's the point? 00:08:45.870 --> 00:08:49.560 We might not use this all the time, as we're going to soon see, 00:08:49.560 --> 00:08:52.370 we use hexadecimal quite a lot as programmers. 00:08:52.370 --> 00:08:55.060 Not necessarily for the purpose of doing math with it, 00:08:55.060 --> 00:08:58.470 but because a lot of times memory addresses in our system 00:08:58.470 --> 00:09:00.440 are represented in hexadecimal. 00:09:00.440 --> 00:09:04.390 It's a really concise way to express otherwise cumbersome, binary numbers. 00:09:04.390 --> 00:09:06.440 And so, again, you may not-- you're probably 00:09:06.440 --> 00:09:07.640 not going to do any math with it, you are not 00:09:07.640 --> 00:09:09.848 going to be multiplying hexadecimal numbers together, 00:09:09.848 --> 00:09:11.770 or doing anything weird like that. 00:09:11.770 --> 00:09:16.120 But it is a useful skill to have so you can express and understand 00:09:16.120 --> 00:09:23.290 memory addresses, and other ways of using data in C. 00:09:23.290 --> 00:09:26.240 >> I'm Doug Lloyd, this is CS50.