字幕列表 影片播放 列印英文字幕 (train whistle) - Hello and welcome to what will undoubtedly be the longest video you've ever watched about binary numbers. So why am I making this challenge here? So I made a coding challenge number 117 called the Seven Segment Display and what I was doing was creating a visual, a JavaScript, HTML, canvas version of the Seven Segment Display and to do that, I had some weird code in there. Val >> shift & 1 and that code, that code right up there made no sense to anybody and I tried to explain it but I got a lot of comments saying I didn't get what this was so this is bit shipping and bit masking. So before I can even get into that, I thought let's take a deep breath and let's just enjoy and go back, backwards in a time days of yore when we didn't have anything but binary numbers and we had to program everything in binary, I don't know, this never happened for me but I can imagine there was a time when this really happened so this is a coding challenge where I will explain what binary numbers are and then I will create a sketch, p5.js sketch in JavaScript that converts a binary number to a decimal number. Okay so maybe you're even asking right now what is a binary number, what is a decimal number? So before I can even answer that, we have to talk about this idea of base. Base is a term that refers to the number of possibilities in a counting system, in a number system. So base 2 or binary, there are only two possibilities, a zero or a one. Base 10, ten, dec, deca, or decimal has 10 possibilities, zero through nine. There are other well-known numbering systems that get used often, probably the one you see in computing the most is base 16 or hexadecimal and this actually has 16 possible digits, zero through nine and also A through F so when you see something like this in CSS like FF 00 FF, this is hexadecimal in coding. This FF in decimal is 255, this 00 in decimal is zero, this FF is 255 so this is the color, this is a representation of the color red of 255, zero of green and blue 255 so anyway, so this kind of encoding of information exists and by the way in my seven segment display, there were hexadecimal representations of what should be displayed on the seven segment display. Okay so hexadecimal is interesting, I'm not going to do hexadecimal conversion in this video but you know, it's important to realize, these are maybe something that you see, I think base 8 is used for some file systems but you can make up anything. If you have base 4, you just have four possibilities, maybe zero, one, two or three. And when I say possibilities, this defines how you count. And by the way, historically there are all sorts of alternative ways of counting. I believe, I was looking, Aztecs used maybe units of zero then 20, then 40, then 800, then 8000 and instead of digits, they were actually drawings of what, so anyway, so you can look that up, somebody will make a nice explainer YouTube video of counting systems but if we have base 2, this means there are only two possibilities. Let's use base 10 decimal 'cause we understand that. 10 fingers, 10 toes, that's why base 10 is the convention. Zero, one, two, three, four, five, six, seven, eight, nine, 10, 11, 12, right 'cause once we get to nine, we've run out of possibilities in a single digit so we switch to zero and then the next digit over, the tens unit becomes a one. This is what kids learn in elementary school in counting in groups of 10, hundreds units, et cetera. All right but if I were doing this in binary, I would say zero, then I would say one and then I have run out of digits, I have no more digits left, so I have to say one zero and then one one and then, uh oh, one zero, zero, then one zero one, one one one, I'm totally, this is the worst drawing ever, and then one zero zero zero, did I get that right? No, I totally did not. One zero zero, one zero one, one one zero, then one one one and then one zero zero zero. Oh this is hard. Okay let me match up some things for you. So something that's really interesting here is one matches up with one. One zero matches up with two, one zero zero matches up with four, five, six, seven, one zero zero zero matches up with eight. Notice that when there is only the leading digit one and everything else is a zero, there's a pattern here. One, two, four, eight, maybe now you could imagine what one zero zero zero zero is going to be. How about 16? Oops, sorry, 16, I should put that over here. One, two, four, eight, 16. These numbers are doubling so in fact, each one of these digits in binary represents not the tens, the twos. So with a one, this is actually one, this is actually two to the zero power. Two, this is two to the one power. This is two squared, two to the third power, we're doubling so this is by the way the algorithm that I need to write in my code to convert from binary representation to decimal representation. Are you ready to do that? I'm ready. So one thing I want to show you first is you can can actually, you don't need to write your own algorithm to do this conversion, this is built in to the way that computers work and actually JavaScript has several helper functions that'll do this for you. I think if I say for example, =0b, if I have a variable that's =0b, I can put any encoding so what if I put one one one one one one one one, now actually the value of, that's actually 255. So this is, I can actually hard code a number in binary by saying 0b. I can also use this parseInt function so if I say parseInt and give it a string like 255, just converts it, the string, to a number. But I could do things like say parseInt one one zero and then give it a radix or, that's another word for base, and say what is the value, the integer value, the decimal integer value of one one zero in base 2, right, it's six. If it were base 10, obviously it's 110. So this will actually be done for you just through that parseInt function but let's go and actually write our own algorithm for this, yes, there is a bell ringing. (bell ringing) And let's go to the web editor. So let's just assume for the sake of argument that the binary numbers that I want to work with are going to be strings. So I am going to make a number and I'm going to make it a binary number and there's a thing about when you have 8 bits, that's kind of important here, right, each one of these is referred to as a bit, each spot in a binary number is a bit. When you have eight of them, that's a byte. And so this has to do with how things are stored in the computer's memory, right, everything ultimately in the depths of your computer is stored in binary format and the amount of space it takes up is the number of bytes or kilobytes or gigabytes, et cetera, terabytes. But I'm going to waste a lot of space and encode my binary number as a string so let's just say, let's just try something really simple like one zero zero and we know that should be four, right? Zero one one zero, no that's not four. Yeah it is four, (chuckles) I lost my mind for a second there, right? This is zero, this is one, this is two, this is three, this is four but we should, yeah, if we do this right, we'll get four. Okay now I want to write a function, I'm going to call it bin, binaryToDecimal, it'll take in any arbitrary value which is a string and we could make this much more generic. By the way, as a challenge to you, what if you made a function like this which is just number convertor, it takes a number and two base, a base and a second base. So here's the number in a given base, give it back to me in another base. It'll be generic, that's a challenge for you to do now or later or whenever you want. Okay, so the thing that I need to do is I need to loop through the... Sorry, i = 0, i < val.length so if it's a string, I'm going to loop through the string one character at a time. So for each character, the way to convert it is to add up all of the twos so for example, one zero one is five because it is one zero zero plus zero zero one is one zero one and this is four and this is one so one zero one is five. So if I just start here and take the first digit multiplied by two and take the second digit multiplied by, sorry multiplied by one, the second digit multiplied by two, the third digit multiplied by four, add all those things together and by the way, it's not just one two four, it's two to the zero, two to the one, two to the two, two to the three. So it's the exponent that's counting up. So I'm going to say sum += pow, now I need to get this value. So I need to get the zero or the one so I'm going to say the bit = val.charAt(i). Now here's the thing, hmm, hmm. This is an interesting question here. What is i when it starts at zero? i is actually a string representation, this is the zero index so even though I want to do the conversion by starting over here, I'm actually over here so I actually want to get to the end of the, I want to start from the end of the array, or not the array, the end of the string and a quick way that I can do that is by saying val., val.length-i-1, right, if there are three digits, I have two one zero, not zero one two, two one zero. So three minus i minus one. So sum = pow(2, bit) and I need to make this a number, I'll just use parseInt 'cause it's a string and then let's just say console.log(sum) and I think we're done sort of (chuckles). Console.log(sum), let's see, let's do binary, binaryToDecimal(val) and actually so this should return a num, sorry, and oh, there we go, four. Let's test some other ones out. Let's add another one. Six. Let's try one zero zero, this is a byte, right, if all the ones are on in a byte, right, everything is on, eight bits is a byte and everything is a one, what do we get? Okay I need one more. Wait, what's going on? Something is wrong. No, this isn't right, I've made a mistake. This code is not correct at all (chuckles). So remember, I am each digit represents a one, a two, a four, two to the (i)th power, I actually even said that somewhere, sometime earlier I said two to the (i)th power, maybe only in my head. So what I'm actually doing is taking that bit and multiplying it. Now of course it's a string so I have to convert it, the string value. Now this is what I'm looking to do and now 255, there we go, boy I had, somehow I was getting some right answers by accident. So that should be four. This should be five, yeah. Whoops, we can't have twos there (chuckles). That should be 18. So I should probably write some error handling, right, because actually, this would actually work if I put a three in there, it's going to give me a number but it makes no sense at all. So and once again, what I wanted to show was that eight bits all on gives me 255. And in fact, this is why we see again the range, you can store 256 possibilities in a single byte, a byte being eight bits, 256 in decimal or two digits in hexadecimal. I'm getting some messages from the chat saying that maybe it would be more intuitive to run the loop backwards. So yes, but then I have, so it's six of one, half dozen of the other as far as I'm concerned because I either have to invert it here or I have to invert it here so I don't know which would be more, I mean I could have a counter so you know I could do this, counter = 0 and I could run the loop backwards and then increase the counter but I don't know, I'm going to stick with what I have, all right, now, I said this was going to be along one and I'm going to let it just be a long one. You want to stick around and keep watching? You can go do something else but what I'm going to do is now make this interactive. So I want to make something where I can actually click here and I can turn on and off bits and see the conversion live. So let's figure out how we're going to do that. So I think I want to use some object oriented programming and I am going to make a class. I'm going to add another JavaScript file called bit.js and I am going to make a bit class and the bit class is going to have a, and let me take off this auto refresh for right now, it's going to have an X. It's going to have an X and a Y and a width, like a size, maybe I'll make it a circle so it's going to have a diameter. I'll use a circle to represent each bit and then it's going to have a state, right, it's state is going to be on or off. Then I'm going to have a show function or render I could call it where I'm going to say a stroke 255, let's make the outline white and should it be, I can never figure this out, is black on, white on, I don't know, maybe I should make it red and blue, we'll figure it out, we'll see how it looks. So I'm going to say draw an ellipse at this.x, this.y, this.diameter and its fill is going to be 255 times this.state. So in this case, it would be white if it's on. So what I want to do now is make an array. And let's just use eight. We'll do a byte so I can call this a byte, oh that's probably a bad word for me to use 'cause maybe that's reserved somewhere in JavaScript but let's say i = 0; i < 8; i ++ and let's make a bit = new Bit(i, so let's say I want to fit all eight across in my, and I could use dom elements or something that's going to be easier to interact with but I'm just going to draw them as circles. So I am going to say, I need to calculate a width which is the width of the canvas divided by eight. So I'm going to say its x value is i * width, its y value will be 50 and its diameter will be w and I'm going to say byte[i] = that bit and I guess I don't need a separate variable here, I'll just do this. And then I want to say here, I want to say byte[i].show. So what do we got? Oh, let me turn back on auto refresh and I've got some errors. Show is undefined. I see a show function. Oh wait, whoops, I put these in the wrong place. The creation of them has to be in setup and this should go in draw, ah, no, stop, don't, ah. All right, bit is not defined, oh of course, I forgot that if I'm adding another JavaScript class, I need to make sure I reference it from my HTML file and now we're seeing and if all of them have a state of on, hmm, I'm not seeing anything, so let's see, oh, I've got to pass in the arguments, x,y,d. So right now I want to set the arguments based on this, there we go, there they are, there's all my bits and maybe I want to offset them a little bit. And maybe I actually want this to be, their diameter to be, have a little buffer in it. Whoops. There we go, so this is looking nice. There are my bits, thank you very much, oh I'm excited about this, this is going to be good. And now if I take this state and state zero, there we go, so now let's make this state, let's actually also initialize the state, I'm just going to write that in a separate, I'm going to set state and I'm going to actually say num.charAt(i). So I'm going to use the character, sorry I'm going to use the individual character there to set the state of the particular bit. Now, set state is not a function 'cause I need to add that in here and I'm going to say setState(state) and I'm going to say this.state = and I'll add parseInt in here just to make sure it's a number and now, what's going on? Set state is not a function, oh byte is not, of course, byte[i].setState, there we go. So now, as I change values in here, it turns those bits on and off. Okay, we're gettin' somewhere. Now what I want to do is I'm going to add a decimal, I'm going to say decimalP, decimalP = createP, (vocalizing) What is, what am I doing? createP and then in the draw loop and it's silly that I have a draw loop here, I don't need to continue to draw but that's something that we can revise later. I'm going to say, where's that function binaryToDecimal? binaryToDecimal, I'm going to say... decimalP.html(binaryToDecimal(num) and so now we should see it says undefined, ooh, oh, 'cause it's console logging it. I want to return sum, okay 182, now you can barely see that so let me go to my CSS for a second and add a color and guess what? I'm going to use hexadecimal. Will it actually do it? No I can use three F's 'cause it'll but let's use six to do RGB and let's also make the font size much bigger. Okay so now and let's actually make this a, it's got this extra, 'cause it's a paragraph element, actually this is so silly but I'm going to make it a div just so it shows up up here, okay, so now, this is not interactive but I can do this and it does feel, it does look inverted, right, this really looks like on, off, on, on, the way that I've kind of drawn this. Somehow the black color looks like I've turned it on so I could probably make the background much darker. If I made the background 51, yeah, so maybe this, I still, I don't know, it's so confusing. What if I made? I don't know which is which, you tell me, my visual design skills are kind of a disaster but if I go back to this, but anyway, whichever way I think it is, I could actually just say 255 minus this and now, right, now it is colored black when it is on and I could say one zero one zero one zero zero one, we can see 169, okay. Should I make this interactive? I mean I've gone on for way too long already. Let's make, 'cause I need to make this interactive, do you know why? Because the whole point of doing this was to talk about bit shifting and bit masking, I'm going to get to that, that I'll do in a separate video. Let's make this interactive. So what do I need here? I need some sort of function to see if this bit contains a point so if, so what I need to do is calculate the distance between this point and its X and Y and then if the distance is less than the radius which is the diameter divided by two and it's this dot diameter. And I'm going to call this toggle, I'm actually just going to, I could return this, I'm going to make this the toggle function, then I'm going to say this.state =, now if the state is a zero, I want it to be a one, if it's a one, I want it to be a zero. What's a nice way of doing that? I mean I could write an if statement. People are giving me great suggestions like +1 module is 2 to the power of -1, I think I'm just going to admit to myself that really what I meant was for this to be true or false (chuckling) so I'm going to, the state's going to be false and when I say set state, I'm going to do parseBoolean, is that a function in JavaScript? Let's see if it is and then I can say not this.state. parseBoolean is not defined (chuckling). There's no parseBoolean? What if I do Boolean? Ah, there we go, okay so boolean is a function I guess that will convert that to this and then here, what I want to do is I could just say if this.state fill(0) and of course this is rather awkward but I don't care, this is how I like to write code, there we go, mm, mm this is no good. Oh you know what? Those are strings. So this needs actually to say parseInt. There we go, okay, we're back, we're back baby. Okay, now this, boy, there's lots of things you can improve, right? All right now what I can do is make these interactive. So I can now add the mouse pressed function and I can just say for and I can loop through again. Once again, I can loop through and this should really be byte.length. I can do this and I can loop through all of them and I can say toggle, oops, no, and I can just call toggle with the mouse coordinates. So it's toggling, the toggling is working but it's not updated. Ooh, why is it not updating? Because, oh, I am converting the string. My function converts a string so I could do something like make that, I could make the decimal version of the number out of the array of bit objects but I think what might actually work nicely here is for to make the string out of it so what if what I do now is I say in here, I'm going to say, I'm just going to use that same variable, num = an empty string and then I'm going to say num +=... Oh this is in setup, sorry, in draw, +=, now I want to have a zero or a one because if I say this dots, byte[i].state. So this is where I have to use but I have to embrace the ternary operator, it's something that I have never natively really understood. It's never fit into my brain but this thing called ternary operator and it looks like this. The condition and if the condition is true, this is the result, if it's false, this is the result. We can make this happen right now. We can use that ternary operator. The condition is actually just byte[i].state. Then I need the question mark and this is so nice, I just need to have if it's true a one or a zero, it's false. Oh I need to say recreate that string, whoa, look, it's going crazy. There we go. Look at this. Now, ooh so lovely, let's go, we did it. (bell ringing) Everybody, we did it, I made a binary thing that you can click on bits and convert it to a binary number. Now here's the thing, oh boy, you, the creative person watching, if you made it to the end of this video, wow, you really are something. Thank you, I can't believe it because this was ridiculously long winded to just explain binary numbers but you now have the opportunity to make something creative here. What if you made, you could make a clock that displays the time in binary. Maybe you could actually also show the hexadecimal value. You could actually make this a form content editable that you can convert backwards, how you convert, this is a thought experiment for you, I can come back and do another video, but how do you convert not form binary to decimal, how would you convert from decimal to binary? I'll give you a hint, it has to do with division and the remainder, I think, so there's so many things you could do, you can make a more interactive version, you can make a counter that's sort of... Ooh this would be fun to have this count up in binary. That's kind of like the clock. You'll be in color, other ways of visualizing it, you'll come up with something, I know you will. You always do. Thank you so much for watching this coding challenge and I will, remember at the beginning when I said the whole point of this was talking about bit shifting and bit masking, I will come back and I will do that. So that will be in a separate challenge. I'm going to add some buttons for shifting and masking. (train whistle) (upbeat music)
A2 初級 編碼挑戰#119:二進制到十進制轉換 (Coding Challenge #119: Binary to Decimal Conversion) 7 0 林宜悉 發佈於 2021 年 01 月 14 日 更多分享 分享 收藏 回報 影片單字