+ ( 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 10decimal ( -- ) Switch stack to decimal mode.
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, 01010 01101 xor = 01111.
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 --------------------- 1000010000110000and ( n1 n2 -- n3 ) Logical and.
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.