Last time we talked about the data types that we use in C to represent whole numbers, integers. This time, we'll talk about the data types we use in C to represent real numbers, or floating point numbers, those numbers with a fractional part, a decimal place. Before we do, let's talk about a core idea that actually limits our ability to represent any floating point number in a computer. So in the real world, there are an infinite number of floating point numbers between zero and one. And we already know that two to the b equal n. So if n is infinity, then b has to be infinity. We'd actually need an infinite number of bit to represent all the numbers between zero and one. And then of course, there are the numbers between one and two, and all those other numbers as well. So we can't actually precisely represent all the numbers in the real world in the continuous domain. In the discrete domain, which is what a computer is, we have a set of bits, and that set of bits is used to represent a particular number. And it turns out that, because we have a limited number of bits, that representation is an approximation of real numbers in the real world. So in fact we'll get essentially rounding error, because a number of those infinite numbers in the real world map to the same sequence of bits in the computer. And it doesn't matter if we decide to use more bits for the number, unless we have infinite bits, and I know memory is cheap, but not that cheap. If we have infinite bits, then we could do it, but we don't have infinite bits. So understanding the distinction between the continuous domain and the discrete domain is an important part of your understanding of the limitations of computers when it comes to floating points numbers. With that said, we can of course, represent floating point numbers in a C program. And the three data types that we'll talk about are float, double, and long double. And in this course, we'll pretty consistently use float but I will point out that each of these three data types are represented with a different number of bit. And what does that tell us? Exactly what it told us with integers. The further along we go from floats to double to long double, the more bits we're using, so the broader range of real numbers we can represent including the precision of those numbers based on how many bits we use for the decimal portion of the number. So as always, two to the b equal n, and if b is bigger, n is bigger. The operations that we use on floats are pretty much what you would expect. There's nothing tricky like division in integers. So let's actually go take a look at an example of using floats in a C program. So I've already created my C program in Visual Studio. And I've even added this comment here. And I've added comments about what we're going to actually do in this particular program. So first we're going to store some collected data. And I'm going to say we are going to store the number of hours we've driven and the number of miles we've driven. So hours driven and I'd just use int for this, would be 5, and miles driven, would be 262. So in five hours we drove 262 miles. If you look at the next comment, you can see that what we're going to do is we're going to calculate and print the miles per hour. So I will come down here and this one will make a float, Miles per hour. And we know that it is miles driven divided by hours driven. So we'll type the equation here, Like that, and we're supposed to print the miles per hour also. So we know how to do that. We do printf, we label our output miles per hour. And let's say that you remember the %d format specifier from before. So you're going to use it here because you've forgotten that %d is for integers. You just remember we're supposed to have something here. So let's print out miles per hour. And let's see what happens when I actually run this code. And our output says that the miles per hour is 0. So I'm going to close that window, I'm going to add an additional line after that because you know I like that. But 0 is definitely the wrong answer and the problem is that %d is a format specifier for integers, %f is a format specifier for floats, so let's try that again. Great, so it says 52, which is better than 0 as an answer but is actually not correct. Because if we took 52 and multiplied by 5 for the hours driven, we only get 260. We lost the decimal part, and the reason is that milesDriven is an integer and hoursDriven is an integer. So this division is that integer division we looked at last time and we know we only get the whole number, we don't get the decimal part. One way we can solve this problem is by saying, for this calculation, treat this as a floating point number or treat this as a floating point number. You can actually force it to treat both of them as a floating point number, but we only need to make one of them a floating point number. So we're going to do something called the type cast. I'm going to put in (float), and that says for this calculation, treat the value in the milesDriven variable as a floating point number. It doesn't actually change the data type of milesDriven, it doesn't change the bits that are contained in that memory location, it just says for this calculation, treat this as a float. So now, when I run it again, I see that I get 52.4, and some change. There's a little bit of rounding error there, because, remember, we have some imprecision in floating point numbers. So let's actually say, though, that we don't really care about all of those decimal places. What we really want to know is to one decimal place. How can we format our output to only output to one decimal place? And the answer is, between the % sign and the f, we can put 0.1. So this is output everything to the left of the decimal point, but only output one digit past the decimal point on the right. So if I run it again, we see that the output is to only one decimal place. It actually turns out that we can also format how wide the entire output of the number is. This would be useful if you were actually outputting tables of numbers or something like that. We can say how wide should the output be for this number, and I've said eight spaces. So if I run it this time, we see we have that big gap between the colon and the 5 in 52.4. I'm going to change this back again, and every time I change my code I run it because I never know when I might break something and we're back to the way we wanted it to be. So what did we look at today? We looked at how to declare a floating point variable. We learned how to use typecasting appropriately to make sure that we got a floating point number as the result of this calculation. Just as a quick caution before I leave this idea, you have to be careful about type-casting. You don't want to do something like this, Because if you do, what happens is it does this math and then it turns it into a float. So if I were to run my code now, you'll see that I'm back to 52.0, that incorrect answer because it does the integer division first and then turns that integer 52 into floating point 52. So you do have to pay attention when you're typecasting and make sure your typecasting is doing what you want it to do. And as always, I'll run it again, and we're back to the way we wanted it to be. So we learned about typecasting. We learned how to format floating point numbers for output, and we saw how to do that just using %f. We saw how to use it specifying how many numbers we want to print out after the decimal point. And we even saw how we could specify the total width of that output. So this is floating point data types in action in a C program. To recap, in this lecture, we learned that C provides a number of different data types for representing floating point numbers. And although we'll pretty consistently use floats in this course, you have other options if you need a wider range of numbers or more precision after the decimal point in those numbers because two to the b equal n.