-4

It seems as though in software engineering, we care more about these "on and off switch" usages of binary numbers more than the actual values of them numbers... For example, say I have the number:

1011

The "value" of this number is decimal 11.

Likewise:

1001 0110 - Value is decimal 150

However, with bit manipulation techniques, the above 2 binary numbers may instead be seen as 4 switches in the first example followed by 8 switches in the second example. Here, we are less concerned about the decimal value that the number holds, and more concerned about whether or not each individual binary digit is set (1) or clear (0).

To give a final illustration, say we have the number above:

1001 0110

We want to set the second-to-highest bit to 1 like this:

1101 0110

We can do this:

1001 0110
OR
0100 0000
=
1101 0110

0100 0000 happens to hold the value of decimal 64. My question is: Is there any significance to the fact that the number we had to use to set that bit happens to be 64? In decimal, we performed 150 OR 64 to get 214. We added 64 to the value of 150 which creates the number 214.

Is it beneficial as a programmer to look at the decimal values of these bitwise interactions, or is there no real use in that, and instead, they are typically viewed simply as positional bit flips to store switches?

  • 2
    TBH I don't have the slightest clue what you're asking about. Binary or decimal representation of numbers are just representations of the same numbers, what you're doing with them regarding oprators will result in the same numbers. – πάντα ῥεῖ Oct 21 '19 at 22:38
  • Everyday software development do not require programmers to be aware of the implementation detail at the "logic gate" level, or the "bitwise" level. It is useful to have the knowledge of the underlying detail, but this knowledge is dormant 99% of the time. – rwong Oct 21 '19 at 23:12
  • 1
    To me, as an experienced programmer, "setting bit 6" and "adding 64" mean exactly the same thing (I have powers of two memorized up until about 65536). There is no particular benefit in looking at it either way because they are interchangeable. – John Wu Oct 22 '19 at 0:30
  • Note that x OR y != x + y. If x already has the bits of y, the result remains X. – marstato Oct 22 '19 at 14:25
3

My question is: Is there any significance to the fact that the number we had to use to set that bit happens to be 64?

There is exactly the same significance to the fact that the ascii character we had to use to set that bit happens to be @.

The concept that you're scratching at is called encoding. 0100 0000 is 64. But it's also @. It's also the settings of 8 switches that you presented as 0 and 1 grouped by nibbles.

Nothing stored in a computer means anything unless you decode it. A byte of bits can be decoded as a whole number and presented as it's base 10 equivalent giving you, in this case, 64. But it doesn't have to be. It could be a pixel in a bitmap.

Is it beneficial as a programmer to look at the decimal values of these bitwise interactions, or is there no real use in that, and instead, they are typically viewed simply as positional bit flips to store switches?

It's as beneficial as memorizing that 40 in hex gives you exactly the same pattern of bits. It's nice to be able to recognize a bit mask when you see it regardless of how it's encoded. Few programers use actual 1's and 0's to build their bit masks.

1<<7 is an old favorite of mine.

  • 1
    Calling number representations in different bases the same as the assignment of letters/characters to numbers is grossly confusing and conflates two dramatically different things. 78 being equal to 0x4E has basically nothing to do with either of them being assigned N – whatsisname Oct 22 '19 at 1:22
  • @whatsisname i have to agree with candied_orange here. After all, the decimal and hexadecimal systems are just another way of assigning a numerical value to sequences of symbols. Admittedly, ASCII is rather arbitrary in comparison, but nonetheless. – marstato Oct 22 '19 at 14:20
  • 1
    @marstato thank you. That 2 means two rather than say half-a-heart seems a little arbitrary as well. Wasn't hard wired. Had to learn it. Think it was Mom who taught me. – candied_orange Oct 22 '19 at 20:56
1

No, there is no meaningful relationship between the decimal and binary notations of the numbers. One is base 10 and the other base 2 and ten is not a power of two.

The reason we use base-10 Arabic numerals is probably because have ten fingers and because it's a much better system then Roman numerals. Nobody was thinking about binary digits at the time.

However, there is a relationship to hexadecimal numbers, which are base 16. 16 is 2^4 so each digit represents four bits (binary digits). This makes going from hexadecimal to binary and vise versa a snap. For instance, if you know that the hex number A (10 decimal) is 1010, then you know right away how to decode the hex number AAAA: 1010101010101010

When you're working with binary numbers and boolean operators hex is a lot more intuitive.

150 OR 64 in decimal is very awkward. I can't do that in my head. But 96h OR 40h is no problem. You only have to think about a single nibble. You know that 9d is 1001 and 4 is 0100 so you know you can add 4 and 9 to get the result: 13d, or Dh. So the answer is D6. The translation from D6 into decimal (13 * 16 + 6=214) however is awkward, so it's nice if you can avoid using decimal.

1

Binary, octal, decimal, hexadecimal are only different means to express the same number.

So it’s not about a special significance, it’s just that 0100 0000 in binary, 64 in decimal and 0x40 in hexadecimal ARE mathematically speaking the same number.

When you write them in binary, it’s just practical (and cheap) to implement them in computers. So the powers of 2 correspond to individual bits according to the general formula for radix conversion.

1

Most things can be used in multiple ways. For example, coins can be used as screwdrivers sometimes. But when a coin is used as a screwdriver, it doesn’t matter that the coin could also be used to buy stuff.

Likewise, when using bit patterns as a set of “on-off switches”, the fact that the pattern also represents a number is irrelevant.

0

Your question is not entirely clear, but hopefully my interpretation of it will be of some value to you.

1011

The "value" of this number is decimal 11.

However, [...] the above [...] may instead be seen as 4 switches

So, both the binary and the decimal number system are based on the same principle; the difference is in the number of available digits.

The binary number system has 2 symbols for digits (conventionally 0 and 1, but it could really be any two distinct things, as long as one is interpreted as "zero", and the other as "one"), so it is base 2 (I'll go into more detail on what that means in a second).

The decimal system uses 10 different symbols (0-9), and is base 10.

When a number is written as a string of digits
...ddddddd
each digit has an implicit multiplier based on it's position; if you index the rightmost digit (least significant digit) as 0, and then increase the indices towards the left, the implicit multiplier is base^index (where ^ is "to the power of" operator); the value of the number is the sum.

For example, the decimal number 123 is actually:
(1 * 10^2) + (2 * 10^1) + (3 * 10^0) == (1 * 100) +(2 * 10) + (3 * 1)
(parentheses added for readability)

You probably know this as ones, tens, hundreds, thousands, etc.

Similarly, the binary number 1011 is:
(1 * 2^3) + (0 * 2^2) + (1 * 2^1) + (1 * 2^0)
or in decimal:
== (1 * 8) + (0 * 4) + (1 * 2) + (1 * 1)
== 8 + 0 + 2 + 1 == 11

Instead of ones, tens, hundreds, ..., you now have ones, twos, fours, eights, etc.

So, it works the same way, except that with decimal it's not a series of two-state switches, but more like a bunch of dials with 10 different positions each. Note that in binary, since the digits are either 0 or 1, the terms in the sum are either zeros or the corresponding powers of 2 (while in decimal, the terms can be any 0-9 multiple of the corresponding power of 10).

1011

The "value" of this number is decimal 11.

One way to think about it is that the value of both numbers is "eleven" (the abstract concept) - it's just that in the binary number system, that value is represented as "1011", while in decimal it is represented as "11".

We want to set the second-to-highest bit to 1 like this:

1001 0110
OR
0100 0000
.=
1101 0110

This is just a consequence of how bitwise OR works - it's a Boolean OR applied to each bit pair.

In decimal, we performed 150 OR 64 to get 214. We added 64 to the value of 150 which creates the number 214

So, while that's not exactly wrong, it isn't quite right either, and it doesn't really describe what happened. The number 64 is a power of 2 (64 == 2^6), and you happened to change the seventh bit from the right (so, at index 6) from 0 to 1, and that in turn added that power of 2 to the total sum. Furthermore, the second number had only a single digit with the value 1 (the seventh one), and this is why it was 64. But, you could have gotten the same result like this:

1001 0110  
OR  
0100 0100    // 68
=    
1101 0110 

Is it beneficial as a programmer to look at the decimal values of these bitwise interactions, or is there no real use in that, and instead, they are typically viewed simply as positional bit flips to store switches?

Well, in general, there isn't necessarily going to be something interesting when doing these conversions, but there are some tricks that you may occasionally use.

First, if you are going to work with and manipulate binary values, it's beneficial to learn the hexadecimal number system, because each hex digit corresponds to one of the possible 4-bit strings (or half a byte - a.k.a. a nibble). See this - you don't necessarily have to memorize the nibbles associated with each hex digit; you can look these tables up if you need them. These can be used to set binary values, or as "masks" during bit manipulation. Also, it will come in handy if you ever need to use a hex editor, and it can help with some other things - like understanding hex color codes in css.

It is also beneficial to learn the powers of 2 (in decimal or hex), as these can be used as "flags" (they all have only a single bit set to 1 in binary representation).

Another trick that can sometimes come in handy is using bit shifting to perform multiplication by 2 (or a power of 2). Assuming unsigned numbers and no loss of data, shifting by one position to the left effectively multiplies the number by 2:

0101 << 1 == 1010 // or 5 --becomes--> 10

Similarly, shifting to the right divides by 2:

1010 >> 1 == 0101 // or 10 --becomes--> 5
0101 >> 1 == 0010 // or 5 --becomes--> 2 (integer division, loss of data, loss of accuracy)

Shifting by n positions multiplies or divides by 2^n. That said, in general, prefer clarity over cleverness in your code, especially if other people are going to read it. I.e., use regular multiplication most of the time, and leave hacks such as this one for situations that require such tricks - for example, this can be used to manipulate pixels of an image in place efficiently; also, when doing something hackish, add comments that clarify the intent (why you are doing it and what you are trying to achieve) - this will be helpful to anyone who is reading the code, including yourself, when you leave the project for a while (and forget the details of what you were doing) and then come back to it.

Not the answer you're looking for? Browse other questions tagged or ask your own question.