3

I am writing a basic calculator for my computer science class which takes in a number between 0-255 and converts it to binary, one's complement, and two's complement. Me and one other student have been working on this together and we are both stuck at the two's complement, it is producing the wrong value. For example if we type in 11 the two's complement should be "1111 1011" but i am getting "1111 0101" and I am not sure what is wrong?

I have started a demo at jsbin.com and I am hoping that someone here can really save my life (and my grade) and tell me what me and my coding partner are doing wrong.

jsbin -> http://jsbin.com/juqevomiliwo/1/edit

Also, I would really like to add in some error checking such as if a user inputs a negative number or if a user inputs a value that is not within the value range of 0-255 could someone assists me with that as well? I would really like to have a pop up say, "i am sorry you need to input a value between 0-255"

I apologize for asking so much but i don't know where else to turn! I have gone to stackoverflow so many times to help assist me with issues and this is my first time posting a problem that I don't know how to solve!

Thank you all so much for your time and your assistance!

-Martin

Here is the code:

<!DOCTYPE html>

<html>
<head>
    <title>Group Project</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
    <h1>Group Project 1</h1>
    <p>Enter a number between 0 and 255 <input id="theInput" type="text" /> <button onclick="doSomething()">Show Binary</button>   </p>
    <p>Unsigned Binary: <span id="binaryOutput"></span></p>
    <p>One's Complement: <span id="onesOutput"></span></p>
    <p>Two's Complement: <span id="twosOutput"></span></p>
    <script>
        function doSomething(){
            var i = document.getElementById('theInput').value; //gets number from input box and sets it to i
            var binary = pad(Number(i).toString(2), 8); //converts i to binary and pads with leading zeros until 8 digits long
            var ones = binary.toString(2).replace(/1/g, 'a').replace(/0/g, '1').replace(/a/g, '0');
            var twos = pad((Number(ones) + 1), 8);

            document.getElementById('binaryOutput').innerHTML = fancy(binary); //puts the binary in the Unsigned Binary field
            document.getElementById('onesOutput').innerHTML = fancy(ones); //puts the ones compliment in the One's Complement field
            document.getElementById('twosOutput').innerHTML = fancy(twos); //puts the twos compliment in the Two's Complement field
        }

        //adds leading zeros to achieve width
        function pad(n, width, z) {
            z = z || '0';
            n = n + '';
            return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
        }

        //adds space every four digits
        function fancy(b) {
            return b.replace( /\d{4}/g, '$& ' ).replace( /\s$/,'');
        }

    </script>
</body>

Martin
  • 31
  • 1
  • Given your current code I'm at a loss as to why you would need help checking if the number is between 0-255. – will Oct 09 '14 at 22:49
  • I just want to do it to try and take care of any issues that might arise and i feel like there should be some error checking in the program something like if n <0 && n> 255 then do a pop up telling the user please enter a correct value. – Martin Oct 10 '14 at 01:02
  • I assume this is a school assignment. :-) – JME Oct 10 '14 at 01:12

2 Answers2

0

In your twos = pad((Number(ones) + 1), 8); line, the Number() function doesn't convert a binary string into a number (it assumes the string is decimal).

You should use twos = pad((parseInt(ones, 2) + 1).toString(2), 8); instead. See snippet below.

function doSomething(){
            var i = document.getElementById('theInput').value; //gets number from input box and sets it to i
            var binary = pad(Number(i).toString(2), 8); //converts i to binary and pads with leading zeros until 8 digits long
            var ones = binary.replace(/1/g, 'a').replace(/0/g, '1').replace(/a/g, '0');
            var twos = pad((parseInt(ones, 2) + 1).toString(2), 8);

            document.getElementById('binaryOutput').innerHTML = fancy(binary); //puts the binary in the Unsigned Binary field
            document.getElementById('onesOutput').innerHTML = fancy(ones); //puts the ones compliment in the One's Complement field
            document.getElementById('twosOutput').innerHTML = fancy(twos); //puts the twos compliment in the Two's Complement field
        }

        //adds leading zeros to achieve width
        function pad(n, width, z) {
            z = z || '0';
            n = n + '';
            return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
        }

        //adds space every four digits
        function fancy(b) {
            return b.replace( /\d{4}/g, '$& ' ).replace( /\s$/,'');
        }
<h1>Group Project 1</h1>
<p>Enter a number between 0 and 255
  <input id="theInput" type="text" />
  <button onclick="doSomething()">Show Binary</button>
</p>
<p>Unsigned Binary: <span id="binaryOutput"></span>
</p>
<p>One's Complement: <span id="onesOutput"></span>
</p>
<p>Two's Complement: <span id="twosOutput"></span>
</p>
JME
  • 3,592
  • 17
  • 24
  • This has been such a big help i can't thank you enough for your time and assistance. You really saved me big! Thank you so much for your expertise advice! – Martin Oct 10 '14 at 05:58
0

Your main mistake is the understanding of one's complement system. Basically, you have to decide whether you have numbers from 0 to 255 or from -127 to 127. Inversion is done only for negative numbers (the first bit at the left is equal to 1) or for numbers above 127, while positive numbers do not change (or numbers from 0 to 127, there is also a negative zero with all bits set to 1, which is one's complement of 255).

So, one's complement of 11 is the same 11 or 0000 1011 and at the two's complement system also does not change it, because there is no need in addition of 1.

As soon as you are talking about signed numbers and your unsigned number is above 127, it sets the highest bit to 1, which indicates the negative sign. So, lets say we have unsigned number 129 = 1000 0001, one's complement will be 1111 1110 (inversion of all bits except of the first one), which is -126. Two's complement of 129's will be 1111 1110 + 1 = 1111 1111 or -127.

As of checkup of the input numbers - something like this

var i = parseInt(document.getElementById('theInput').value); 
if (i < 0 || i > 255 || isNaN(i)) { alert('Invalid input number'); return;}

And, as it was said before, var twos = pad((parseInt(ones, 2) + 1).toString(2), 8);

ps: http://jsbin.com/jahesosafana/1/edit

there is one interesting moment about number 128: -128 and 128 in 2's complement

In two's complement notation, a non-negative number is represented by its ordinary binary representation; in this case, the most significant bit is 0. Though, the range of numbers represented is not the same as with unsigned binary numbers. For example, an 8-bit unsigned number can represent the values 0 to 255 (11111111). However a two's complement 8-bit number can only represent positive integers from 0 to 127 (01111111), because the rest of the bit combinations with the most significant bit as '1' represent the negative integers −1 to −128.

Community
  • 1
  • 1
Cheery
  • 16,063
  • 42
  • 57
  • thank you all who responded you guys have been so great in assisting me with this school project! I knew that it had to do something with the way i was adding the "1" to the two's complement but i wasn't exactly sure of the conversion that needed to be done and how i was to go about adding it one's complement value to get the proper two's complement value. – Martin Oct 10 '14 at 05:56
  • @Martin Do not forget to accept the answer you think is the most useful. – Cheery Oct 10 '14 at 17:21