**+** ( n1 n2 -- n3 ) Add n1 to n2.

**-** ( n1 n2 -- n3 ) Subtract n2 from n1.

***** ( n1 n2 -- n3 ) Multiply n1 by n2.

**/** ( n1 n2 -- quot ) Divide n1 by n2, return the quotient.

**1+** ( n1 -- n2 ) Add 1 to n1.

**1-** ( n1 -- n2 ) Subract 1 from n1.

**2+** ( n1 -- n2 ) Add 2 to n1.

**2-** ( n1 -- n2 ) Subtract 2 from n1.

**2*** ( n1 -- n2 ) Multiply 2 by n1.

**2/** ( n1 -- quot ) Divides n1 by 2, return the quotient.

They are also provided because they run much faster precompiled than
if you ran each seperately. Therefore, `1+` executes much more
quickly than `1 +`. Of course, you would never know the
difference unless you had many iterations of the operator. The
following two words compare the speed of execution of the single
operator and double operator: (more about the do...loop later)

ok : test1 1 date 10000000 0 do 1+ loop date ; ok test1 Wed May 3 14:38:13 EDT 1995 Wed May 3 14:38:20 EDT 1995 ok : test2 1 date 10000000 0 do 1 + loop date ; ok test2 Wed May 3 14:38:49 EDT 1995 Wed May 3 14:39:14 EDT 1995The single operator only took ~7 seconds to add one to a number ten million times. The dual operator version took ~25 seconds, a speed decrease of over 300 percent. (Computations done on a SUN IPX with a SPARC PowerUP chip and CFORTH)

***/** ( n1 n2 n3 -- quot ) n1 times n2, divide by n3,
return the quotient.

**mod** ( n1 n2 -- rem ) n1 divided by n2, return the
remainder.

**/mod** ( n1 n2 -- rem quot ) n1 divided by n2, return the
remainder and the quotient.

***/mod** ( n1 n2 n3 -- rem quot ) n1 times n2, divide by
n3, return the remainder and then the quotient.

ok 10 .s 10 ok h# 10 .s \ Place a hex number on the decimal stack. 10 16 ok o# 10 .s \ Place an octal number on the decimal stack. 10 16 8 ok b# 10 .s \ Place a binary number on the decimal stack. 10 16 8 2 ok hex .s \ Switch to hex mode. a 10 8 2 ok octal .s \ Switch to octal mode. 12 20 10 2 ok binary .s \ Switch to binary mode. 1010 10000 1000 10 ok d# 10 .s \ Place a decimal number on the binary stack. 1010 10000 1000 10 10

**binary** ( -- ) Switch stack to binary mode.

**hex** ( -- ) Switch stack to hex mode.

**octal** ( -- ) Switch stack to octal mode.

**d#** ( "integer" -- n ) Place a decimal number on the
stack.

**b#** ( "integer" -- n ) Place a binary number on the
stack.

**h#** ( "integer" -- n ) Place a hex number on the
stack.

**o#** ( "integer" -- n ) Place an octal number on the
stack.

In addition to decimal, octal, hex and binary, you can specify the
base you want by changing the value in the `base` variable:

ok 10 .s 10 ok 3 base ! \ ! is the command to store a number at an address. \ More on this later... ok .s 101

NOTE: A bit is a single boolean number, 1 or 0. A byte is currently defined as 8 bits. One byte can be any number from -128 to 127, 2^8 possible numbers. Our computers are currently 32 bit. The byte is still defined to be 8 bits, but an integer is defined to be 4 bytes long. This gives us a total of 2^32 possible 4-byte integers: 4,294,967,296! The range of numbers supported is -2,147,483,648...2,147,483,647. In binary, though, the range of numbers is 11111111111111111111111111111111 to 01111111111111111111111111111111 (32 ones to 31 ones). The one on the far left is called the Most Significant Bit because it determines whether the number is positive or negative. Let's look at a number line in binary, decimal and hex (base 16):

BINARY (actual representation) DECIMAL HEX 11111111111111111111111111111111 -1 -1 ... 10000000000000000000000000000000 -2,147,483,648 -80000000 01111111111111111111111111111111 2,147,483,647 7fffffff ... 00000000000000000000000000000001 1 1 00000000000000000000000000000000 0 0I say that the binary column is an actual representation because CFORTH will report -1 in decimal as -1 in binary, -10 in decimal as -1010 in binary. You can see which method is easier to read and compute.

Examples of binary arithmetic (the top row is the decimal representation of the corresponding binary statements underneath):

10 AND 13 10 OR 13 10 XOR 13 10 NOT 1010 1010 1010 1101 and 1101 or 1101 xor 1000 not -------- ------- -------- -------- 1000 == 8 1111 == 15 0111 == 7 -0111 == -9So what's going on here? The AND example shows that both bits need to be true for the result to be true. Any other combination ( 1 0, 0 1, 0 0) yields a false value. The OR example shows that any combination of 1 and 0 yields a true value and only a pair of zeroes returns false. The third example, XOR, shows that for any non-zero pair, the answer is true. You can always add a zero to the front of a binary number without its value changing. So,

The last example, NOT, is a bit peculiar. Instead of returning a true
or false answer, it returns one's complement, the equivalent of
subtracting each bit from one. This means that all bits are changed
from zero to one or one to zero. This includes the bit which
determines whether a number is positive or negative, usually referred
to as the most significant bit (MSB). In order to determine whether a
number is true or false, you should use `0=` as mentioned
above.

Let's say that we have a binary number,`1000010000110100`,
which refers to the current state of an A/D converter. We would like
to change the third bit (2^2) to a 0 (i.e. turn off that bit). This
would be done by taking a binary number which corresponds to just that
third bit being on, 0000000000000100, finding its one's complement and
then anding them together. To turn bit 3 on again, simply take the
binary number representing the current state and `or` it to a
binary number with only the third bit true.

OFF: ON: 0000000000000100 not 1000010000110000 --------------------- 100 or -1111111111111011 ------------------- 1000010000110100 -1111111111111011 1000010000110100 and --------------------- 1000010000110000

**or** ( n1 n2 -- n3 ) Logical or.

**xor** ( n1 n2 -- n3 ) Exclusive or.

**not** ( n1 -- n2 ) One's complement: for positive numbers
subtract n1 from -1, for negative numbers add to -1.

Top: Forth Index Prev: Defining Words Next: Making Decisions