Bits, Bytes, and Bases: Write a JavaScript Binary/Decimal/Hexadecimal Converter
Abstract
This is a challenging first computer science project. You'll learn the basics of how digital devices can represent numbers using only 0's and 1's, and you'll write a JavaScript program to convert numbers between binary, decimal and hexadecimal notation.Summary
- Write a basic HTML file with a text editing program (like Notepad);
- Create HTML <FORM> elements for user input;
- Write basic JavaScript functions using Arrays, Strings and simple flow control statements (e.g., if...else, and for or while loops).
Objective
The objective of this project is to write a JavaScript program that can convert numbers between their binary, decimal and hexadecimal representations. The number to be converted can be supplied as a binary, decimal or hexadecimal number. The program then automatically displays the number in the other two representations.Introduction
This is an example of an advanced first-time programming project. You will learn the basics of how digital devices can represent numbers using only 0's and 1's. You will be writing a simple program to convert numbers between binary, decimal and hexadecimal notation.
Prerequisites
It is assumed that you know how to use a text editor to write an HTML file containing your program, and that you know how to load and run the file in your browser.
You will also need to know the basics of how JavaScript functions can be written to work with HTML FORM elements. Specifically, you will be working with HTML INPUT elements, and using JavaScript String and Array objects and for loop statements in your functions.
If you need help with any of this, read the Introduction section in: "ABC's of Programming: Writing a Simple 'Alphabetizer' with JavaScript" For help with writing loops, read the Introduction section in: "Paragraph Stats: Writing a JavaScript Program to 'Measure' Text"."
Decimal and Digital: Base 10 and Base 2
You've been using decimal (base 10) numbers all your life, so by now they are second nature to you. You probably know that there are other ways to represent numbers. For example, computers and other digital devices store everything using binary (base 2) numbers, that is, numbers made up of only 0's and 1's. This is because it is much easier to distinguish between binary levels (on/off) than between the ten different levels (0–9) it would take to encode decimal numbers.
So how can you represent numbers using only 0's and 1's? Well, it's the same principle as for decimal numbers. Each digit represents a place value. For decimal (base 10) numbers, the place values are increasing powers of ten, as shown in the table below.
Decimal Representation of 3,897 | ||||
---|---|---|---|---|
place value (words) | thousands | hundreds | tens | ones |
exponential notation | 10^{3} | 10^{2} | 10^{1} | 10^{0} |
which is the same as | 10×10×10 | 10×10 | 10 | 1 |
N | 1000 | 100 | 10 | 1 |
digit indicates how many N | 3 | 8 | 9 | 7 |
Quick tutorial on exponential notation (you can skip this if you know it already).
Exponential notation is a compact way of expressing multiples of a number. For example, as you saw in the table:An equivalent statement in words is: Ten to the third power equals ten times ten times ten which is also equal to one thousand.
The exponent (3, in this case), tells how many times to multiply the base (10, in this case). Any number raised to the 0^{th} power is equal to 1. That's it!
For binary (base 2) numbers it is similar, but now there are only two digits available (0 and 1), and the place values are increasing powers of two. The next table shows the same number (3,897) in binary representation. Obviously, it takes a lot more digits than in base ten!
Binary Representation of 3,897 is: 1111 0011 1001 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
exponential notation | 2^{11} | 2^{10} | 2^{9} | 2^{8} | 2^{7} | 2^{6} | 2^{5} | 2^{4} | 2^{3} | 2^{2} | 2^{1} | 2^{0} |
N | 2048 | 1024 | 512 | 256 | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
digit indicates how many N | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 1 |
Check it out for yourself and make sure that it all adds up!
Bits and Bytes
Each binary digit is called a bit. Use the table above to see how many bits it takes to represent 3,897. Go ahead, we'll wait.
That's right, twelve bits. The right-most bit (the "one" bit) is the least significant bit and the left-most bit (the "two-thousand forty-eight" bit) is the most significant bit. Since it is easy to lose your place when reading a long string of 0's and 1's, binary numbers are often displayed in 4-bit groups, like this: 1111 0011 1001.
Two of these 4-bit groups (eight bits altogether) make a byte, which is the basic unit for measuring the size of a digital memory or storage device. What can you store in one byte? Think about how many different numbers can be encoded with one byte. (It may help to make an analogy with decimal numbers first: how many different numbers can you encode with 2 digits? how many with 3 digits?)
A kilobyte (abbreviated kB) is not 1000 bytes, as you might think if you know your metric prefixes. Since this is the digital world, everything is in powers of 2, so a kilobyte is 1024 bytes ( = 2^{10} bytes). Similarly, a megabyte (MB) is 1024×1024 bytes ( = 1,048,576 bytes = 2^{20} bytes).
Hexadecimal: Base 16
Binary numbers are fine for computers, but are not particularly handy for people to use. However, when you are programming a machine that works with binary numbers, it is sometimes handy to work with numbers represented as powers of 2 instead of powers of 10. Hexadecimal notation (base 16) is often used for this reason. As you would expect, in hexadecimal there are 16 digits, and each digit represents a power of 16. We use decimal digits for 0–9, and the first six letters of the alphabet, A–F, for the hexadecimal digits corresponding to decimal numbers 10–15. The table below shows the first 16 numbers (starting with zero) in binary, hexadecimal and decimal notation.
Binary, Hexadecimal and Decimal Numbers | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Binary | 0000 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 |
Hexadecimal | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
Decimal | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
Since 16 = 2^{4}, it is not surprising to see that one hexadecimal digit corresponds to 4 bits. Can you see what the hexadecimal representation for 3,897 would be?
Another interesting fact that you may have noticed is that the least significant bit of the binary representation indicates whether the number is odd or even. Error correction code algorithms for transmitting and receiving data (used in everything from NASA satellite transmissions to cell phones to CD players) often make use of this property.
An easy way to have your input elements aligned neatly is to use an HTML <TABLE> element (an example is shown below). The table has two columns. Each input is a separate row in the table. The labels are in the first column, and the input fields are in the second column. The labels are aligned at the right-hand edge of their column, and the input fields are aligned at the left-hand edge of their column. The HTML code for this sample table is also shown (beneath the table itself).
<FORM METHOD="post">
<TABLE style="text-align:center; border-style:solid; cellpadding:10%" >
<TR>
<TH COLSPAN="2">Binary/Decimal/Hexadecimal Converter Interface Example</TH>
</TR>
<TR>
<TD style="text-align:right;"><B>Binary: </B></TD>
<TD style="text-align:left;"><INPUT NAME="bin" VALUE="0" "readonly" onChange="ConvertBin(form)" SIZE=10></INPUT></TD>
</TR>
<TR>
<TD style="text-align:right;"><B>Decimal:</B></TD>
<TD style="text-align:left;"><INPUT NAME="dec" VALUE="0" "readonly" onChange="ConvertDec(form)" SIZE=10></INPUT></TD>
</TR>
<TR>
<TD style="text-align:right;"><B>Hexadecimal:</B></TD>
<TD style="text-align:left;"><INPUT NAME="hex" VALUE="0" "readonly" onChange="ConvertHex(form)" SIZE=10></INPUT></TD>
</TR>
</TABLE>
</FORM>
Notes on the HTML table code. Note that the size of each input element in the table is the same. You will have to figure out appropriate sizes for your input elements so that they accommodate the same range of values (remember that binary numbers generally require more digits). Notice that the each of the input elements uses the onChange event to call a JavaScript function. Thus, when the user changes a value, this function is called to update the values for the other two representations. We've only attempted to cover a few key points to get you started, not every detail about how the table is put together. There is a reference in the Bibliography with detailed information on writing HTML tables. By using that reference, you should be able to answer any remaining questions you have about the table.
The first entry in the Bibliography is an excellent reference for information on writing a base conversion algorithm. Combined with the material available here, you should be able to put together a binary/decimal/hexadecimal converter.
By the way, so you can check your answers to the questions from earlier in the Introduction:
- One byte can encode 256 (2^{8}) unique values.
- The hexadecimal representation for 3,897 is "F39". Each hexadecimal digit corresponds to 4 bits of the binary representation: 1111 0011 1001.
Terms and Concepts
To do this project, you should understand the following terms and concepts (do background research to fill in any gaps in your knowledge):- binary (base 2),
- decimal (base 10),
- hexadecimal (base 16),
- bit, byte, kilobyte (kB), megabtye (MB),
- radix (number base).
- Basic HTML concepts:
- start tags and end tags,
- comments,
- the <HEAD> section,
- the <SCRIPT> section,
- the <BODY> section,
- the <FORM> section,
- the <INPUT> tag,
- the <TABLE> tag, for aligning your s neatly.
- JavaScript concepts:
- functions,
- variables,
- objects,
- properties,
- methods,
- events,
- arrays.
- General programming concepts:
- reserved words,
- control statements (e.g., "if...else" statements, "for" and "while" loops)
- operators:
- arithmetic operators: plus, minus, times, divide, modulus (+, -, *, /, %),
- assignment operators: e.g., =,+=,-=,*=,/=,
- comparison operators: e.g., <,>,<=,>=,==,
- logical operators: AND, OR and NOT, (&&,||,!).
Questions
- Using the binary representation of integers described in the Introduction, how many unique integers can be represented with 8 bits? With 12 bits? With n bits, where n is a positive integer?
- Using the hexadecimal representation of integers described in the Introduction, how many unique integers can be represented with 2 hexadecimal digits? With 3 hexadecimal digits? With n hexadecimal digits, where n is a positive integer?
Bibliography
Explanation of a JavaScript implementation of base conversion:
- Bogomolny, A. (n.d.). Implementation of Base Conversion Algorithms from Interactive Mathematics Miscellany and Puzzles. Retrieved March 17, 2014.
You can find a step-by-step JavaScript tutorial at the link below. After studying the tutorial, you should be able to answer all of the questions listed above, and you'll be ready to write a simple calculator.
- Webteacher Software. (2006). JavaScript Tutorial for the Total Non-Programmer. Webteacher Software, LLC. Retrieved June 6, 2006.
Introduction to Programming by Matt Gemmell describes what programming actually is:
- Gemmell, M. (2007). Introduction to Programming. Dean's Director Tutorials & Resources. Retrieved March 14, 2014.
HTML Forms reference:
- W3C. (1999). Forms in HTML Documents, HTML 4.01 Specification. World Wide Web Consortium: Massachusetts Institute of Technology, Institut National de Recherche en Informatique et en Automatique, Keio University. Retrieved June 6, 2006.
HTML Tables reference:
- W3C. (1999). Tables in HTML Documents. World Wide Web Consortium: Massachusetts Institute of Technology, Institut National de Recherche en Informatique et en Automatique, Keio University. Retrieved June 6, 2006.
A list of reserved words in JavaScript (you cannot use these words for function or variable names in your program, because they are reserved for the programming language itself):
- JavaScript Kit. (2006). JavaScript Reserved Words. Retrieved June 6, 2006.
A JavaScript reference:
- Mozilla Developer Network and Individual Contributors. (2013, December 14). JavaScript reference. Retrieved March 14, 2014.
If you get interested and start doing a lot of web development, you may want to use a text editor that is a little more sophisticated than Notepad. An editor designed for web development and programming can help with formatting so that your code is more readable, but still produce plain text files. This type of editor can also fill in web-specific HTML coding details and do "syntax highlighting" (e.g., automatic color-coding of HTML), which can help you find errors. There are many options available—search online for "free HTML editor" to find one.
Materials and Equipment
- Computer with web browser
- Text-editing program like Notepad, or a more advanced editor of your choice
Experimental Procedure
- Using what you have learned about integer representation in different bases and programming in JavaScript, create a binary/decimal/hexadecimal converter.
- The program should have separate input fields for each type of number. Remember that binary representations generally use more digits than decimal or hexadecimal representations, so adjust the sizes of your input fields accordingly.
- Use the input field's onChange event so that when the user enters a number in one of the fields, the other two are updated with the new number, converted to the appropriate base.
- There are several sub-tasks here. Take the sub-tasks one at a time, and gradually build up the capabilities of your program.
- Verify that the code for each sub-task is working properly before moving on to the next sub-task.
- Test your program by verifying conversions from each type of input.
- Plan your work.
- Methodically think through all of the steps to solve your programming problem.
- Try to parcel the tasks out into short, manageable functions.
- Think about the interface for each function: what arguments need to be passed to the function so that it can do its job?
- Use careful naming, good formatting, and descriptive comments to make your code
understandable.
- Give your functions and variables names that reflect their purpose in the program. A good choice of names makes the code more readable.
- Indent the statements in the body of a function so it is clear where the function code begins and ends.
- Indent the statements following an "if", "else", "for", or "while" control statement. That way you can easily see what statements are executed for a given branch or loop in your code.
- Descriptive comments are like notes to yourself. Oftentimes in programming, you'll run into a problem similar to one you've solved before. If your code is well-commented, it will make it easier to go back and re-use pieces of it later. Your comments will help you remember how you solved the previous problem.
- Work incrementally.
- When you are creating a program, it is almost inevitable that along the way you will also create bugs. Bugs are mistakes in your code that either cause your program to behave in ways that you did not intend, or cause it to stop working altogether. The more lines of code, the more chances for bugs. So, especially when you are first starting, it is important to work incrementally. Make just one change at a time, make sure that it works as expected and then move on.
- With JavaScript, this is easy to do. To check your code, all you need to do is use your web browser to open the HTML file containing your code. After you've made a change in the code with your text editor, just save the file, then switch to your browser and hit the re-load page button to see the change in action.
- Test to make sure that your code works as expected. If your code has branch points that depend on user input, make sure that you test each of the possible branch points to make sure that there are no surprises.
- Also, it's a good idea to backup your file once in awhile with a different name. That way, if something goes really wrong and you can't figure it out, you don't need to start over from scratch. Instead you can go back to an earlier version that worked, and start over from there.
- As you gain more experience with a particular programming environment, you'll be able to write larger chunks of code at one time. Even then, it is important to remember to test each new section of code to make sure that it works as expected before moving on to the next piece. By getting in the habit of working incrementally, you'll reduce the amount of time you spend identifying and fixing bugs.
- When debugging, work methodically to isolate the problem.
- We told you above that bugs are inevitable, so how do you troubleshoot them? Well, the first step is to isolate the problem: which line caused the program to stop working as expected? If you are following the previous tip and working incrementally, you can be pretty sure that the problem is with the line you just wrote.
- Check for simple typos first. A misspelled function name will not be recognized. In JavaScript, a misspelled variable name simply creates a new variable. This is an easy mistake to make, and can be hard to find.
- Avoid using reserved words as variable or function names.
- Test your program thoroughly.
- You should test the program incrementally as you write it, but you should also test the completed program to make sure that it behaves as expected.
Ask an Expert
Variations
- Add functions to check each input to make sure that only appropriate digits are entered. Use the built-in JavaScript alert() function to pop up a message telling the user what the problem is and asking them to enter a valid number.
- Generalize your converter to handle base 2 to base 36 (when the alphabet runs out of letters for more digits).
- The converter you wrote is designed for unsigned integers (the positive integers plus zero). What about negative numbers? For a more advanced project, do research to learn how negative numbers are represented in binary notation and extend your converter to handle negative numbers.
- What about rational numbers? For a much more advanced project, do research to learn how "floating point" numbers are represented in binary notation and extend your converter to handle these numbers.
Careers
If you like this project, you might enjoy exploring these related careers: