In the C programming language, operations can be performed on a bit level using bitwise operators.
Employee scheduling software automates the process of creating and managing shift schedules according to rules and parameters set by the organization. In Shiftboard’s case, it also includes workforce management functionality, such as time and attendance. Change the position of command line arguments passed to a batch file. Syntax SHIFT /n Key /n Start at the nth argument, where n is between zero and eight. You can get the value of any argument using a% followed by it's numerical position on the command line. The first item passed is always%1 the second item is always%2 and so on. Shift is the desktop app for streamlining your accounts, apps, and workflows. Shifting Retail.
Bitwise operations are contrasted by byte-level operations which characterize the bitwise operators' logical counterparts, the AND, OR and NOT operators. Instead of performing on individual bits, byte-level operators perform on strings of eight bits (known as bytes) at a time. The reason for this is that a byte is normally the smallest unit of addressable memory (i.e. data with a unique memory address).
This applies to bitwise operators as well, which means that even though they operate on only one bit at a time they cannot accept anything smaller than a byte as their input.
All of these operators are also available in C++, and many C-family languages.
Bitwise operators[edit]
C provides six operators for bit manipulation.[1]
Symbol | Operator |
---|---|
& | bitwise AND |
| | bitwise inclusive OR |
^ | bitwise XOR (exclusive OR) |
<< | left shift |
>> | right shift |
~ | bitwise NOT (one's complement) (unary) |
Bitwise AND &
[edit]
bit a | bit b | a & b (a AND b) |
---|---|---|
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
The bitwise AND operator is a single ampersand: &
. It is just a representation of AND which does its work on the bits of the operands rather than the truth value of the operands. Bitwise binary AND does the logical AND (as shown in the table above) of the bits in each position of a number in its binary form.
For instance, working with a byte (the char type):
The most significant bit of the first number is 1 and that of the second number is also 1 so the most significant bit of the result is 1; in the second most significant bit, the bit of second number is zero, so we have the result as 0. [2]
Bitwise OR |
[edit]
bit a | bit b | a | b (a OR b) |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
Similar to bitwise AND, bitwise OR only operates at the bit level. Its result is a 1 if either of the bits is 1 and zero only when both bits are 0. Its symbol is |
which can be called a pipe.
Bitwise XOR ^
[edit]
bit a | bit b | a ^ b (a XOR b) |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
The bitwise XOR (exclusive or) performs a logical XOR function, which is equivalent to adding two bits and discarding the carry. The result is zero only when we have two zeroes or two ones.[3] XOR can be used to toggle the bits between 1 and 0. Thus i = i ^ 1
when used in a loop toggles its values between 1 and 0.[4]
Bitwise NOT ~
/ ones' complement (unary)[edit]
The bitwise complement operator, the tilde, ~, flips every bit. A useful way to remember this is that the tilde is sometimes called a twiddle, and the bitwise complement twiddles every bit: if you have a 1, it's a 0, and if you have a 0, it's a 1.
This turns out to be a great way of finding the largest possible value for an unsigned number:
1 | unsigned int max = ~0; |
0, of course, is all 0s: 00000000 00000000. Once we twiddle 0, we get all 1s: 11111111 11111111. Since max is an unsigned int, we don't have to worry about sign bits or twos complement. We know that all 1s is the largest possible number.
Note that ~ and ! cannot be used interchangeably. When you take the logical NOT of a non-zero number, you get 0 (FALSE). However, when you twiddle a non-zero number, the only time you'll get 0 is when every bit is turned on. (This non-equivalence principle holds true for bitwise AND too, unless you know that you are using strictly the numbers 1 and 0. For bitwise OR, to be certain that it would be equivalent, you'd need to make sure that the underlying representation of 0 is all zeros to use it interchangeably. But don't do that! It'll make your code harder to understand.)
Now that we have a way of flipping bits, we can start thinking about how to turn off a single bit. We know that we want to leave other bits unaffected, but that if we have a 1 in the given position, we want it to be a 0. Take some time to think about how to do this before reading further.
We need to come up with a sequence of operations that leaves 1s and 0s in the non-target position unaffected; before, we used a bitwise OR, but we can also use a bitwise AND. 1 AND 1 is 1, and 0 AND 1 is 0. Now, to turn off a bit, we just need to AND it with 0: 1 AND 0 is 0. So if we want to indicate that car 2 is no longer in use, we want to take the bitwise AND of XXXXX1XX with 11111011.
How can we get that number? This is where the ability to take the complement of a number comes in handy: we already know how to turn a single bit on. If we turn one bit on and take the complement of the number, we get every bit on except that bit:
1 | ~(1<<position) |
Now that we have this, we can just take the bitwise AND of this with the current field of cars, and the only bit we'll change is the one of the car_num we're interested in.
1 2 3 4 | void set_unused(int car_num)
|
You might be thinking to yourself, but this is kind of clunky. We actually need to know whether a car is in use or not (if the bit is on or off) before we can know which function to call. While this isn't necessarily a bad thing, it means that we do need to know a little bit about what's going on. There is an easier way, but first we need the last bitwise operator: exclusive-or.
Shift operators[edit]
There are two bitwise shift operators. They are
- Right shift (
>>
) - Left shift (
<<
)
Right shift >>
[edit]
The symbol of right shift operator is >>
. For its operation, it requires two operands. It shifts each bit in its left operand to the right.The number following the operator decides the number of places the bits are shifted (i.e. the right operand).Thus by doing ch >> 3
all the bits will be shifted to the right by three places and so on.
However, do note that a shift operand value which is either a negative number or is greater than or equal to the total number of bits in this value results in undefined behavior. For example, when shifting a 32 bit unsigned integer, a shift amount of 32 or higher would be undefined.
Example:
- If the variable
ch
contains the bit pattern11100101
, thench >> 1
will produce the result01110010
, andch >> 2
will produce00111001
.
Here blank spaces are generated simultaneously on the left when the bits are shifted to the right. When performed on an unsigned type or a non-negative value in an signed type, the operation performed is a logical shift, causing the blanks to be filled by 0
s (zeros). When performed on a negative value in a signed type, the result is technically implementation-defined (compiler dependent),[5] however most compilers will perform an arithmetic shift, causing the blank to be filled with the set sign bit of the left operand.
Right shift can be used to divide a bit pattern by 2 as shown:
Right shift operator usage[edit]
Typical usage of a right shift operator in C can be seen from the following code.
Example:
The output of the above program will be
Left shift <<
[edit]
The symbol of left shift operator is <<
. It shifts each bit in its left-hand operand to the left by the number of positions indicated by the right-hand operand. It works opposite to that of right shift operator. Thus by doing ch << 1
in the above example we have 11001010
.Blank spaces generated are filled up by zeroes as above.
However, do note that a shift operand value which is either a negative number or is greater than or equal to the total number of bits in this value results in undefined behavior. This is defined in the standard at ISO 9899:2011 6.5.7 Bit-wise shift operators.For example, when shifting a 32 bit unsigned integer, a shift amount of 32 or higher would be undefined.
Left shift can be used to multiply an integer by powers of 2 as in
Example: a simple addition program[edit]
The following program adds two operands using AND, XOR and left shift (<<).
Bitwise assignment operators[edit]
C provides a compound assignment operator for each binary arithmetic and bitwise operation (i.e. each operation which accepts two operands). Each of the compound bitwise assignment operators perform the appropriate binary operation and store the result in the left operand.[6]
The bitwise assignment operators are as follows:
Symbol | Operator |
---|---|
&= | bitwise AND assignment |
|= | bitwise inclusive OR assignment |
^= | bitwise exclusive OR assignment |
<<= | left shift assignment |
>>= | right shift assignment |
Logical equivalents[edit]
Four of the bitwise operators have equivalent logical operators. They are equivalent in that they have the same truth tables. However, logical operators treat each operand as having only one value, either true or false, rather than treating each bit of an operand as an independent value. Logical operators consider zero false and any nonzero value true. Another difference is that logical operators perform short-circuit evaluation.
The table below matches equivalent operators and shows a and b as operands of the operators.
Bitwise | Logical |
---|---|
a & b | a && b |
a | b | a || b |
a ^ b | a != b |
~a | !a |
!=
has the same truth table as ^
but unlike the true logical operators, by itself !=
is not strictly speaking a logical operator. This is because a logical operator must treat any nonzero value the same. To be used as a logical operator !=
requires that operands be normalized first. A logical not applied to both operands won’t change the truth table that results but will ensure all nonzero values are converted to the same value before comparison. This works because !
on a zero always results in a one and !
on any nonzero value always results in a zero.
Example:
The output of the above program will be
See also[edit]
References[edit]
- ^Kernighan; Dennis M. Ritchie (March 1988). The C Programming Language (2nd ed.). Englewood Cliffs, NJ: Prentice Hall. ISBN0-13-110362-8. Archived from the original on 2019-07-06. Retrieved 2019-09-07.CS1 maint: discouraged parameter (link) Regarded by many to be the authoritative reference on C.
- ^ ab'Tutorials - Bitwise Operators and Bit Manipulations in C and C++'. cprogramming.com.
- ^'Exclusive-OR Gate Tutorial'. Basic Electronics Tutorials.
- ^'C++ Notes: Bitwise Operators'. fredosaurus.com.
- ^'ISO/IEC 9899:2011 - Information technology -- Programming languages -- C'. www.iso.org.
- ^'C/C++ Compound assignment operators'. XL C/C++ V8.0 for AIX. IBM. Retrieved 11 November 2013.CS1 maint: discouraged parameter (link)
External links[edit]
Definitions
- Abscissa
- The x-coordinate
- Ordinate
- The y-coordinate
- Shift
- A translation in which the size and shape of a graph of a function is not changed, butthe location of the graph is.
- Scale
- A translation in which the size and shape of the graph of a function is changed.
- Reflection
- A translation in which the graph of a function is mirrored about an axis.
Common Functions
Part of the beauty of mathematics is that almost everything builds upon something else, and ifyou can understand the foundations, then you can apply new elements to old. It is this abilitywhich makes comprehension of mathematics possible. If you were to memorize every piece ofmathematics presented to you without making the connection to other parts, you will 1) becomefrustrated at math and 2) not really understand math.
There are some basic graphs that we have seen before. By applying translations to these basicgraphs, we are able to obtain new graphs that still have all the properties of the old ones. Byunderstanding the basic graphs and the way translations apply to them, we will recognize eachnew graph as a small variation in an old one, not as a completely different graph that we havenever seen before. Understanding these translations will allow us to quickly recognize andsketch a new function without having to resort to plotting points.
These are the common functions you should know the graphs of at this time:
- Constant Function: y = c
- Linear Function: y = x
- Quadratic Function: y = x2
- Cubic Function: y = x3
- Absolute Value Function: y = |x|
- Square Root Function: y = sqrt(x)
- Greatest Integer Function: y = int(x) was talked about in the last section.
Constant Function | Linear Function | Quadratic Function |
Cubic function | Absolute Value function | Square Root function |
Your text calls the linear function the identity function and the quadratic function the squaringfunction.
Translations
There are two kinds of translations that we can do to a graph of a function. They are shifting andscaling. There are three if you count reflections, but reflections are just a special case of thesecond translation.
Shifts
A shift is a rigid translation in that it does not change the shape or size of the graph of thefunction. All that a shift will do is change the location of the graph. A vertical shiftadds/subtracts a constant to/from every y-coordinate while leaving the x-coordinate unchanged. A horizontal shift adds/subtracts a constant to/from every x-coordinate while leaving the y-coordinate unchanged. Vertical and horizontal shifts can be combined into one expression.
Shifts are added/subtracted to the x or f(x) components. If the constant is grouped with the x,then it is a horizontal shift, otherwise it is a vertical shift.
Scales (Stretch/Compress)
A scale is a non-rigid translation in that it does alter the shape and size of the graph of thefunction. A scale will multiply/divide coordinates and this will change the appearance as well asthe location. A vertical scaling multiplies/divides every y-coordinate by a constant while leavingthe x-coordinate unchanged. A horizontal scaling multiplies/divides every x-coordinate by aconstant while leaving the y-coordinate unchanged. The vertical and horizontal scalings can becombined into one expression.
Scaling factors are multiplied/divided by the x or f(x) components. If the constant is groupedwith the x, then it is a horizontal scaling, otherwise it is a vertical scaling.
Reflections
A function can be reflected about an axis by multiplying by negative one. To reflect about the y-axis, multiply every x by -1 to get -x. To reflect about the x-axis, multiply f(x) by -1 to get -f(x).
Putting it all together
Consider the basic graph of the function: y = f(x)
All of the translations can be expressed in the form:
y = a * f [ b (x-c) ] + d
Vertical | Horizontal | |
---|---|---|
Scale | a | b |
Shift | d | c |
acts normally | acts inversely |
Digression
Understanding the concepts here are fundamental to understanding polynomial and rationalfunctions (ch 3) and especially conic sections (ch 8). It will also play a very big roll inTrigonometry (Math 117) and Calculus (Math 121, 122, 221, or 190).
Earlier in the text (section 1.2, problems 61-64), there were a series of problems which wrote theequation of a line as:
x/a + y/b = 1
Where a was the x-intercept and b was the y-intercept of the line. The 'a' could really bethought of how far to go in the x-direction (an x-scaling) and the 'b' could be thought of as howfar to go in the 'y' direction (a y-scaling). So the 'a' and 'b' there are actually multipliers (even though they appear on the bottom). What they are multiplying is the 1which is on the right side. x+y=1 would have an x-intercept and y-intercept of1.
Okay. Consider the equation: y = f(x)
This is the most basic graph of the function. But transformations canbe applied to it, too. It can be written in the format shown to the below.
In this format, the 'a' is a vertical multiplier and the 'b' is a horizontal multiplier. We know that 'a' affects the y because it is grouped with the y and the 'b' affects the x because it is grouped with the x.
The 'd' and 'c' are vertical and horizontal shifts, respectively. We know that they are shifts because they are subtracted from the variable rather than being divided into the variable, which would make them scales.
In this format, all changes seem to be the opposite of what you would expect. If you have theexpression (y-2)/3, it is a vertical shift of 2 to the right (even though it says y minus 2) and it is avertical stretching by 3 (even though it says y divided by 3). It is important to realize that in thisformat, when the constants are grouped with the variable they are affecting, the translation is theopposite (inverse) of what most people think it should be.
However, this format is not conducive to sketching with technology,because we like functions to be written as y =, rather than (y-c)/d =. So, if you take the notation above and solve it for y, you get the notation below, which issimilar, but not exactly our basic form state above.
y = a * f( (x-c) / b ) + d
Note that to solve for y, you have had to inverse both the 'a' and 'd' constants. Instead of dividing by 'a', you are now multiplying by 'a'. Well, it used to be that you had to apply the inverse of the constant anyway. When it said 'divide by a', you knew thatitmeant to 'multiplyeach y by a'. When it said 'subtract d', you knew that you really had to 'add d'. You havealready applied the inverse, so don't do it again! With the constants affectingthe y, since they have been moved to the other side, take them at face value.If it says multiply by 2, do it, don'tdivide by 2.
However, the constants affecting the x have not been changed. They are still the opposite ofwhat you think they should be. And, to make matters worse, the 'x divided b' that really meansmultiply each x-coordinate by 'b' has been reversed to be written as 'b times x' so that it reallymeans divide each x by 'b'. The 'x minus c' really means add c to each x-coordinate.
So, the final form (for technology) is as above:
y = a * f [ b (x-c) ] + d
Ok, end of digression.
Normal & Inverse Behavior
You will notice that the chart says the vertical translations are normal and the horizontaltranslations are inversed. For an explanation of why, read the digression above. The concepts inthere really are fundamental to understanding a lot of graphing.
Examples
- y=f(x)
- No translation
- y=f(x+2)
- The +2 is grouped with the x, therefore it is a horizontal translation. Since it is addedto the x, rather than multiplied by the x, it is a shift and not a scale. Since it says plusand the horizontal changes are inversed, the actual translation is to move the entiregraph to the left two units or 'subtract two from every x-coordinate' while leaving they-coordinates alone.
- y=f(x)+2
- The +2 is not grouped with the x, therefore it is a vertical translation. Since it is added,rather than multiplied, it is a shift and not a scale. Since it says plus and the verticalchanges act the way they look, the actual translation is to move the entire graph twounits up or 'add two to every y-coordinate' while leaving the x-coordinates alone.
- y=f(x-3)+5
- This time, there is a horizontal shift of three to the right and vertical shift of five up. Sothe translation would be to move the entire graph right three and up five or 'add threeto every x-coordinate and five to every y-coordinate'
- y=3f(x)
- The 3 is multiplied so it is a scaling rather than a shifting. The 3 is not grouped withthe x, so it is a vertical scaling. Vertical changes are affected the way you think theyshould be, so the result is to 'multiply every y-coordinate by three' while leaving the x-coordinates alone.
- y=-f(x)
- The y is to be multiplied by -1. This makes the translation to be 'reflect about the x-axis' while leaving the x-coordinates alone.
- y=f(2x)
- The 2 is multiplied rather than added, so it is a scaling instead of a shifting. The 2 isgrouped with the x, so it is a horizontal scaling. Horizontal changes are the inverse ofwhat they appear to be so instead of multiplying every x-coordinate by two, thetranslation is to 'divide every x-coordinate by two' while leaving the y-coordinatesunchanged.
- y=f(-x)
- The x is to be multiplied by -1. This makes the translation to be 'reflect about the y-axis' while leaving the y-coordinates alone.
- y=1/2 f(x/3)
- The translation here would be to 'multiply every y-coordinate by 1/2 and multiplyevery x-coordinate by 3'.
- y=2f(x)+5
- There could be some ambiguity here. Do you 'add five to every y-coordinate and thenmultiply by two' or do you 'multiply every y-coordinate by two and then add five'? This is where my comment earlier about mathematics building upon itself comes intoplay. There is an order of operations which says that multiplication and division isperformed before addition and subtraction. If you remember this, then the decision iseasy. The correct transformation is to 'multiply every y-coordinate by two and thenadd five' while leaving the x-coordinates alone.
- y=f(2x-3)
- Now that the order of operations is clearly defined, the ambiguity here about whichshould be done first is removed. The answer is not to 'divide each x-coordinate by twoand add three' as you might expect. The reason is that problem is not written in standard form. Standard form is y=f[b(x-c)]. When written in standard form, thisproblem becomes y=f[2(x-3/2)]. This means that the proper translation is to'divide every x-coordinate by two and add three-halves' while leaving the y-coordinates unchanged.
- y=3f(x-2)
- The translation here is to 'multiply every y-coordinate by three and add two to every x-coordinate'. Alternatively, you could change the order around. Changes to the x or ycan be made independently of each other, but if there are scales and shifts to the samevariable, it is important to do the scaling first and the shifting second.
Translations and the Effect on Domain & Range
Any horizontal translation will affect the domain and leave the range unchanged. Any verticaltranslation will affect the range and the leave the domain unchanged.
Apply the same translation to the domain or range that you apply to the x-coordinates or the y-coordinates. This works because the domain can be written in interval notation as the intervalbetween two x-coordinates. Likewise for the range as the interval between two y-coordinates.
In the following table, remember that domain and range are given in interval notation. If you'renot familiar with interval notation, then please check the prerequisite chapter. The first line is thedefinition statement and should be used to determine the rest of the answers.
Graph | Translation | Domain | Range |
---|---|---|---|
y=f(x) | none | (-2,5) | [4,8] |
y=f(x-2) | right 2 | (0,7) | [4,8] |
y=f(x)-2 | down 2 | (-2,5) | [2,6] |
y=3f(x) | multiply each y by 3 | (-2,5) | [12,24] |
y=f(3x) | divide each x by 3 | (-2/3,5/3) | [4,8] |
y=2f(x-3)-5 | multiply each y by 2 and subtract 5; add 3 to every x | (1,8) | [3,11] |
y=-f(x) | reflect about x-axis | (-2,5) | [-8,-4] |
y=1/f(x) | take the reciprocal of each y | (-2,5) | [1/8,1/4] |
Notice on the last two that the order in the range has changed. This is because in intervalnotation, the smaller number always comes first.
Really Good Stuff
Understanding the translations can also help when finding the domain and range of a function. Let's say your problem is to find the domain and range of the function y=2-sqrt(x-3).
Begin with what you know. You know the basic function is the sqrt(x) and you know the domainand range of the sqrt(x) are both [0,+infinity). You know this because you know those sixcommon functions on the front cover of your text which are going to be used as building blocksfor other functions.
Function | Translation | Domain | Range | |
---|---|---|---|---|
Begin with whatyou know | y=sqrt(x) | None | [0,+infinity) | [0,+infinity) |
Apply thetranslations | y=-sqrt(x) | Reflect about x-axis | [0,+infinity) | (-infinity,0] |
y=2-sqrt(x) | Add 2 to each ordinate | [0,+infinity) | (-infinity,2] | |
y=2-sqrt(x-3) | Add 3 to each abscissa | [3,+infinity) | (-infinity,2] |
So, for the function y=2-sqrt(x-3), the domain is x≥3 and the range is y≤2.
Shift Indicator
And the best part of it is that you understood it! Not only did you understand it, but you wereable to do it without graphing it on the calculator.
There is nothing wrong with making a graph to see what's going on, but you should be able tounderstand what's going on without the graph because we have learned that the graphingcalculator doesn't always show exactly what's going on. It is a tool to assist your understandingand comprehension, not a tool to replace it.
Shift In Supply Curve
It is this cohesiveness of math that I want all of you to 'get'. It all fitstogether so beautifully.