## Doubles, Triples and Quads

By default, numbers entered into Forth are assumed to be 16-bit (either -32768 to 32767 signed, or 0 to 65535 unsigned), and the results of arithmetic operations are also 16-bit.

Forth is capable of working with 32-bit (double) numbers, 48-bit number (triples) and 64-bit numbers (quads). Sorry folks, this is where it gets a little weird. A 32-bit number is created by placing a dot at the end of the number, without a space. Let’s look at doing this in hex first, as it’s easier to follow. In this example, we put Forth into base 16 (hex) first, then we enter the 32-bit number suffixed with a dot, then look at the stack:

Forth is capable of working with 32-bit (double) numbers, 48-bit number (triples) and 64-bit numbers (quads). Sorry folks, this is where it gets a little weird. A 32-bit number is created by placing a dot at the end of the number, without a space. Let’s look at doing this in hex first, as it’s easier to follow. In this example, we put Forth into base 16 (hex) first, then we enter the 32-bit number suffixed with a dot, then look at the stack:

hex

12345678.

.s

**.s**gives the output

**5678 1234**. The 32-bit number is stored as two 16-bit numbers on the stack, with the most-significant 16 bits as the top of stack. It looks backwards to us, but to FlashForth it makes sense. It will work with the 32-bit number correctly.

Now for a 32-bit number in decimal:

decimal

67898.

.s

**.s**gives the output

**2362 1**.

It’s not an error. That’s decimal

**67898**split across two 16-bit words. The

**1**at the top of the stack represents

**65636**(a full 16-bit number… $ffff + 1). 65636 + 2362 = 67898. Rest assured the number is stored correctly, it just appears a little odd when you (a human) looks at the stack in decimal. Keep this in mind when working with doubles, triples and quads.

To view a 32-bit (double) number in a more readable way, use the

**d.**(“d dot”) word to print it out as a double:

67898.

d.

There are a number of words that perform double arithmetic:

A 32-bit constant can be created using the word

**d+**adds two double numbers, while**d-**subtracts one double number from the other.**d2***multiplies by the double number by 2, while**d2/**divides by 2.**m+**adds single number (16-bit) to a double (32-bit) number.**m***multiples two signed 16-bit numbers to give a 32-bit result.**um***does an unsigned multiply on two 16-bit numbers to give a 32-bit result.**ud***multiplies an unsigned 32-bit number with a 16-bit number giving a 32-bit result.**um/mod**divides an unsigned double by an unsigned single, leaving the 16-bit remainder and 16-bit quotient on the stack.**ud/mod**is an unsigned 32-bit/16-bit division, leaving a 16-bit remainder and 32-bit quotient on the stack.**sm/rem**divides a signed double by a signed single, leaving the 16-bit remainder and 16-bit quotient on the stack.**m*/**performs a multiplication and division. On the stack is a signed double, and two signed singles (d1, n1, n2). The operator multiples d1 by n1, then divides by n2.**um*/**performs an unsigned multiplication of a double by single, then division by a single (ud1, u1, u2). The operator multiples ud1 by u1, then divides by u2.**dabs**converts a double to its absolute value.**dnegate**negates a double number.A 32-bit constant can be created using the word

**2constant**. First a double is placed on the stack, then the double constant is created:1272772. 2constant myDConstant

A 32-bit variable can be created using the word

**2variable**, and accessed using**2!**And**2@**. First a double is placed on the stack, then the double constant is created:2variable my32bitVar

1272772. my32bitVar 2!