LT4335 float instructions. Version of 8 July 2011. Home.

Fundamental is that a float consists of two full-fledged integers, one for the mantissa, and one for the exponent. A float is null if the mantissa or exponent or both are null. In this regard, the LT4335 differs from most other CPUs.

Register notation like "#0 exp, #1 man" or "#0.1" indicates a float whose exponent is in #0 and mantissa is in #1. To make the float operations work, if an exponent is in #n, the corresponding mantissa must be in #(n+1). A convenient consequence is that an integer in #0 may be converted to a float in #0.1 simply by pushing an integer zero.

There is no need to inform the CPU that two registers combine to make a float, as the CPU does not enforce data types in registers or genspace. At all times may integer or string operations be performed on the exponent's and mantissa's respective contents. Example: to multiply a float by 2, simply perform the integer operation of adding 1 to its exponent, leaving the mantissa untouched. The programmer is cautioned, however, that tinkering with the mantissa and exponent separately is error prone.

To normalize a float is to do this:

• If the mantissa is null:
• If the exponent is null, do nothing.
• If the exponent has a value, change it to null.
• If the mantissa has a value:
• If the exponent is null, change the mantissa to null.
• If the exponent has a value:
• If the mantissa is zero, change the exponent to zero.
• If the mantissa is nonzero, perform this step…
• Divide the mantissa by two, and add 1 to the exponent
…until either the mantissa is an odd number, or the exponent attains the maximum integer value.

To trim a float is to perform integer trimming on each of its mantissa and exponent. When a float is an input to an instruction, there is no requirement that it be normalized or trimmed. If a programmer does desire to both normalize a float and trim its component integers, the normalization should normally be done first.

The first three tables contain instructions that will get or put the mantissa and exponent of a float. The address within genspace for a float is specifically the address of its mantissa, its exponent immediately following.

Because a float is built of two integers, the programmer could use two integer instructions to get or put a float. If this is preferred, the mantissa and exponent need not adjoin in genspace, but can be widely separated. However, with two separate instructions the operation will no longer be atomic and hence will risk fouling an environment where data is shared among tasks. If this is a concern, a branch uninterruptable operation can be invoked.

With the size-embedded versions of the get, put, and get-and-put instructions a tradeoff in the instruction design was necessary: the size of each of the mantissa and exponent cannot be freely chosen from 0…255, but rather must be a multiple of 17, which is the word size of the LT4335. In an opcode like that of FGAE, m4_e4_00_000_1111, there is first an unsigned four-bit integer (m4) giving the size of the mantissa, in words — not bits. That is followed by another unsigned four-bit integer (e4), this one giving the size of the exponent in words. Therefore, B1000 means one word = 17 bits, B0100 = 34 bits, B1010 = 85 bits, et cetera. A likely popular choice is the sequence B1100_1000 which gives a mantissa of 51 bits and an exponent of 17 bits. The reason for employing word-size, and not bit-size, granularity is that an opcode is only 17 bits long, and two 8-bit size specifiers would leave only one bit, which is hardly enough to distinguish several instructions.

When the size operands are in registers, the limitations of the previous paragraph do not apply; the mantissa and exponent can be of arbitrary sizes, and those sizes need not be calculated until run time. Similarly, there is no size restriction when separate integer instructions are used to get or put the mantissa and exponent.

In the descriptions below:

• m8 is a signed 8-bit integer (−127…+127 or null) for the mantissa of a tiny float (FG_E instruction only)
• e4 is either:
• a signed 4-bit integer (−7…+7 or null) for the exponent of a tiny float (FG_E instruction only)
• an unsigned 4-bit integer (0…15) for the size (in words) of the exponent of a float
• m4 is an unsigned 4-bit integer (0…15) for the size (in words) of the mantissa of a float.
• u8 is an unsigned 8-bit integer (0…255)
• s9 is a signed 9-bit integer (−255…+255 or null).
Sometimes the size of a mantissa or exponent is represented by a signed integer; an exception will be thrown in response to a requested size greater than 255, less than 0, or null.

Many of the get, put, and get-and-put instructions involve an offset. This number, when added to the address of the next physical instruction (which equals the address of the current instruction plus 17), gives the address in genspace whence to read data, or whither to write it. If the offset is null, an exception is thrown.

Get. (see also integer and string) All the float get instructions normalize and trim the result as it is placed into registers. If an unnormalized or untrimmed float is preferred, the programmer should use string get instructions.

The first get instruction pushes a float embedded in the opcode, while the rest get the float from genspace.

FG_E FG_AE FG_AR FG_AE_Y float get, value embedded m8_e4_01_001 Pulled: none Pushed: • #0 exp, #1 man: data retrieved Embedded is a tiny float, with 8 bits for the mantissa and 4 for the exponent. float get, absolute address, sizes embedded m4_e4_000_10_1111 float get, absolute address, all operands in registers 08_000_10_1111 Pulled: • #0 signed integer: address to read in genspace Pushed: • #0 exp, #1 man: data retrieved m4 and e4 are how many words to retrieve for the mantissa and exponent. If both zero, FG_AR is performed instead. Pulled: • #0 signed integer: address to read in genspace • #1 signed integer in 0…255: how many bits to retrieve for exponent • #2 signed integer in 0…255: how many bits to retrieve for mantissa Pushed: • #0 exp, #1 man: data retrieved float get, absolute address, sizes embedded, synchronized m4_e4_100_10_1111 float get, absolute address, all operands in registers, synchronized 08_100_10_1111 Same as FG_AE, plus synchronization. If m4 and e4 are both zero, FG_AR_Y is performed instead. Same as FG_AR, plus synchronization. float get, relative address, offset embedded s9_01_10_1111 Pulled: • #0 signed integer in 0…255: how many bits to retrieve for exponent • #1 signed integer in 0…255: how many bits to retrieve for mantissa Pushed: • #0 exp, #1 man: data retrieved s9 is the offset. float get, relative address, sizes embedded m4_e4_010_10_1111 float get, relative address, all operands in registers 08_010_10_1111 Pulled: • #0 signed integer: offset Pushed: • #0 exp, #1 man: data retrieved m4 and e4 are how many words to retrieve for the mantissa and exponent. If both zero, FG_RR is performed instead. Pulled: • #0 signed integer: offset • #1 signed integer in 0…255: how many bits to retrieve for exponent • #2 signed integer in 0…255: how many bits to retrieve for mantissa Pushed: • #0 exp, #1 man: data retrieved float get, relative address, offset embedded, synchronized s9_11_10_1111 Same as FG_RO, plus synchronization. float get, relative address, sizes embedded, synchronized m4_e4_110_10_1111 float get, relative address, all operands in registers, synchronized 08_110_10_1111 Same as FG_RS, plus synchronization. If m4 and e4 are both zero, FG_RR_Y is performed instead. Same as FG_RR, plus synchronization.

Intentionally omitted is an option to embed an 8-bit mantissa size but place the exponent size in a register, and vice versa.

Put. (see also integer and string) The next instructions pull an float from the stack and write it into genspace. They attempt to convert each of the mantissa and exponent from the size it assumed in its register to the size requested for genspace, which is likely different from the trimmed size. Rounding-nearest-half-even may be necessary, and a reduction in digits may incur a null.

FP_AE FP_AR FP_AE_Y FP_AR_Y float put, absolute address, sizes embedded m4_e4_000_01_1111 float put, absolute address, all operands in registers 08_000_01_1111 Pulled: • #0 exp, #1 man: data to write • #2 signed integer: the address to write in genspace Pushed: none m4 and e4 are how many words to write for the mantissa and exponent. If both zero, FP_AR is performed instead. Pulled: • #0 exp, #1 man: data to write • #2 signed integer: address to write in genspace • #3 signed integer in 0…255: how many bits to write for exponent • #4 signed integer in 0…255: how many bits to write for mantissa Pushed: none float put, absolute address, sizes embedded, synchronized m4_e4_100_01_1111 float put, absolute address, all operands in registers, synchronized 08_100_01_1111 Same as FP_AE, plus synchronization. If m4 and e4 are both zero, FP_AR_Y is performed instead. Same as FP_AR, plus synchronization. float put, relative address, offset embedded s9_01_01_1111 Pulled: • #0 exp, #1 man: data to write • #1 signed integer in 0…255: how many bits to write for exponent • #2 signed integer in 0…255: how many bits to write for mantissa Pushed: none s9 is the offset. float put, relative address, sizes embedded m4_e4_010_01_1111 float put, relative address, all operands in registers 08_010_01_1111 Pulled: • #0 exp, #1 man: data to write • #2 signed integer: offset Pushed: none m4 and e4 are how many words to write for the mantissa and exponent. If both zero, FP_RR is performed instead. Pulled: • #0 exp, #1 man: data to write • #2 signed integer: offset • #3 signed integer in 0…255: how many bits to write for exponent • #4 signed integer in 0…255: how many bits to write for mantissa Pushed: none float put, relative address, offset embedded, synchronized s9_11_01_1111 Same as FP_RO, plus synchronization. float put, relative address, sizes embedded, synchronized m4_e4_110_01_1111 float put, relative address, all operands in registers, synchronized 08_110_01_1111 Same as FP_RS, plus synchronization. If m4 and e4 are both zero, FP_RR_Y is performed instead. Same as FP_RR, plus synchronization.

Get-and-(conditional)-put. (see also integer and string) The machine compares the float in genspace to the "old value" float:

• If they both have values, and they are equal: the "new value" float is written to genspace in place of the old value, and the one-bit string 1 is pushed.
• If either is null, or they are unequal: genspace is not changed, and the one-bit string 0 is pushed.

It is not necessary that the numbers have been normalized or trimmed. For example, here are two numbers that would test as equal:

• mantissa 01110000 = 14 and exponent 0011111 = −4; this number is 14 ÷16 = 0.875
• mantissa 11100 = 7 and exponent 101111 = −3; this number is 7÷8 = 0.875

The two floats must be of exactly the same value; there is no provision for a tolerance. (If an exact match of bit patterns is desired, the string version of get-and-put should be used.) If the "new value" float is of such large or small magnitude that its exponent will not fit into the indicated region of genspace, a null will be written instead.

FGP_AE FGP_AR FGP_AE_Y FGP_AR_Y float get-and-put, absolute address, sizes embedded m4_e4_000_11_1111 float get-and-put, absolute address, all operands in registers 08_000_11_1111 Pulled: • #0 signed integer: the address to examine in genspace • #1 exp, #2 man: old value • #3 exp, #4 man: new value Pushed: • #0 one-bit string: result m4 and e4 are how many words in genspace to examine for the mantissa and exponent. If both zero, FGP_AR is performed instead. Pulled: • #0 signed integer: address to examine in genspace • #1 signed integer in 0…255: how many bits in genspace to examine for exponent • #2 signed integer in 0…255: how many bits in genspace to examine for mantissa • #3 exp, #4 man: old value • #5 exp, #6 man: new value Pushed: • #0 one-bit string: result float get-and-put, absolute address, sizes embedded, synchronized m4_e4_100_11_1111 float get-and-put, absolute address, all operands in registers, synchronized 08_100_11_1111 Same as FGP_AE, plus synchronization. If m4 and e4 are both zero, FGP_AR_Y is performed instead. Same as FGP_AR, plus synchronization. float get-and-put, relative address, offset embedded s9_01_11_1111 Pulled: • #0 signed integer in 0…255: how many bits in genspace to examine for exponent • #1 signed integer in 0…255: how many bits in genspace to examine for mantissa • #2 exp, #3 man: old value • #4 exp, #5 man: new value Pushed: • #0 one-bit string: result s9 is the offset. float get-and-put, relative address, sizes embedded m4_e4_010_11_1111 float get-and-put, relative address, all operands in registers 08_010_11_1111 Pulled: • #0 signed integer: offset • #1 exp, #2 man: old value • #3 exp, #4 man: new value Pushed: • #0 one-bit string: result m4 and e4 are how many words in genspace to examine for the mantissa and exponent. If both zero, FGP_RR is performed instead. Pulled: • #0 signed integer: offset • #1 signed integer in 0…255: how many bits in genspace to examine • #2 exp, #3 man: old value • #4 exp, #5 man: new value Pushed: • #0 one-bit string: result float get-and-put, relative address, offset embedded, synchronized s9_11_11_1111 Same as FGP_RO, plus synchronization. float get-and-put, relative address, sizes embedded, synchronized m4_e4_110_11_1111 float get-and-put, relative address, all operands in registers, synchronized 08_110_11_1111 Same as FGP_RE, plus synchronization. If m4 and e4 are both zero, FGP_RR_Y is performed instead. Same as FGP_RR, plus synchronization.

Versus. (see also integer, string, and branch) Two floats may be compared with each other. The result is a string at #0, which contains 32 bits. Its contents are:

Address of bit within #0new With FV_E and FV_R, this bit equals 1 when … Comments
0#0.1old and #2.3old both have values, and #0.1old > #2.3old never both 1exact comparison, analogous to integer and string
1#0.1old and #2.3old both have values, and #0.1old ≤ #2.3old
2#0.1old and #2.3old both have values, and #0.1old ≠ #2.3old never both 1
3#0.1old and #2.3old both have values, and #0.1old = #2.3old
4#0.1old and #2.3old both have values, and #0.1old < #2.3old never both 1
5#0.1old and #2.3old both have values, and #0.1old ≥ #2.3old
6#0.1old is null never the sameanalogous to integer
7#0.1old has a value
8#2.3old is null never the same
9#2.3old has a value
10#0.1old and #2.3old are similar never the same
11#0.1old and #2.3old are dissimilar
12#0.1old has a value, and #2.3old is null never the same
13#0.1old is null, or #2.3old has a value
14#0.1old is null, and #2.3old has a value never the same
15#0.1old has a value, or #2.3old is null
16#0.1old has a value, and #2.3old has a value never the same
17#0.1old is null, or #2.3old is null
18#0.1old is null, and #2.3old is null never the same
19#0.1old has a value, or #2.3old has a value
20#0.1old and #2.3old both have values, and #0.1old > #2.3old never both 1absolute tolerance
21#0.1old and #2.3old both have values, and #0.1old ≤ #2.3old
22#0.1old and #2.3old both have values, and #0.1old ≠ #2.3old never both 1
23#0.1old and #2.3old both have values, and #0.1old = #2.3old
24#0.1old and #2.3old both have values, and #0.1old < #2.3old never both 1
25#0.1old and #2.3old both have values, and #0.1old ≥ #2.3old
26#0.1old and #2.3old both have values, and #0.1old > #2.3old never both 1relative tolerance
27#0.1old and #2.3old both have values, and #0.1old ≤ #2.3old
28#0.1old and #2.3old both have values, and #0.1old ≠ #2.3old never both 1
29#0.1old and #2.3old both have values, and #0.1old = #2.3old
30#0.1old and #2.3old both have values, and #0.1old < #2.3old never both 1
31#0.1old and #2.3old both have values, and #0.1old ≥ #2.3old

A comparand is regarded as null if the mantissa, the exponent, or both are null. The programmer can investigate the component integers if greater detail is required.

 FV_E FV_R float versus, tolerance embedded s9_1111_0111 float versus, tolerance in register 081_1111_0111 Pulled: • #0 exp, #1 man: comparand • #2 exp, #3 man: comparand Pushed: • #0 32-bit string: result If s9 is null, FV_R is performed instead. Pulled: • #0 exp, #1 man: comparand • #2 exp, #3 man: comparand • #4 unsigned integer: tolerance Pushed: • #0 32-bit string: result

The absolute and relative tolerances are most easily described by reference to the number produced by the FIL instruction, namely the base-two logarithm of a float's absolute value, rounded to an integer, rounded toward negative infinity.

• For absolute tolerance, the instruction subtracts one comparand from the other. If the FIL of that difference is less than or equal to the tolerance, the numbers are deemed equal, not greater-than, and not less-than.
• For relative tolerance, define the anchor to be the comparand of greater absolute value. The instruction subtracts the other comparand from the anchor to obtain the deviation. Next the FIL of the deviation is subtracted from the FIL of the anchor; and if that difference is greater than or equal to the tolerance, the numbers are deemed equal, not greater-than, and not less-than.
• Whether tolerance is absolute or relative, in the case where both comparands happen to be exactly equal they are of course regarded as equal, not greater-than, and not less-than.

The absolute and relative tolerance comparisons are not intended to be a comprehensive error-management system. Rather, they are a quick and easy way to determine whether two floats are "very nearly" equal, and can be beneficial to iterative numerical routines that must frequently test for a termination condition.

Arithmetic. (see also integer) Float arithmetic offers the usual operations. The output will be null on overflow, null input, or division by zero. Null or not, the float will be normalized, and each component integer trimmed.

The precision is the number of bits that the mantissa will have before normalization or trimming, and all those bits are guaranteed accurate according to the round-nearest-half-even rule; this is a relative precision, not an absolute. If the requested precision is not in 0…255, an exception will be thrown. When the precision is embedded in the opcode, it is the first eight bits.

FA_E FA_R FS_E FS_R float add, precision embedded u8_00000_0111 float add, precision in register 08_00000_0111 Pulled: • #0 exp, #1 man: augend • #2 exp, #3 man: addend Pushed: • #0 exp, #1 man = #0.1old + #2.3old If u8 is zero, FA_R is performed instead. Pulled: • #0 exp, #1 man: augend • #2 exp, #3 man: addend • #4 signed integer in 0…255: precision Pushed: • #0 exp, #1 man = #0.1old + #2.3old float subtract, precision embedded u8_10000_0111 float subtract, precision in register 08_10000_0111 Pulled: • #0 exp, #1 man: minuend • #2 exp, #3 man: subtrahend Pushed: • #0 exp, #1 man = #0.1old − #2.3old If u8 is zero, FS_R is performed instead. Pulled: • #0 exp, #1 man: minuend • #2 exp, #3 man: subtrahend • #4 signed integer in 0…255: precision Pushed: • #0 exp, #1 man = #0.1old − #2.3old float negate, precision embedded u8_01000_0111 float negate, precision in register 08_01000_0111 Pulled: • #0 exp, #1 man: negand Pushed: • #0 exp, #1 man = 0 − #0.1old If u8 is zero, FS_0R is performed instead. Pulled: • #0 exp, #1 man: negand • #3 signed integer in 0…255: precision Pushed: • #0 exp, #1 man = 0 − #0.1old float multiply, precision embedded u8_11000_0111 float multiply, precision in register 08_11000_0111 Pulled: • #0 exp, #1 man: multiplicand • #2 exp, #3 man: multiplier Pushed: • #0 exp, #1 man = #0.1old × #2.3old If u8 is zero, FM_R is performed instead. Pulled: • #0 exp, #1 man: multiplicand • #2 exp, #3 man: multiplier • #4 signed integer in 0…255: precision Pushed: • #0 exp, #1 man = #0.1old × #2.3old float divide, precision embedded u8_00100_0111 float divide, precision in register 08_00100_0111 Pulled: • #0 exp, #1 man: dividend • #2 exp, #3 man: divisor Pushed: • #0 exp, #1 man = #0.1old ÷ #2.3old If u8 is zero, FD_R is performed instead. Pulled: • #0 exp, #1 man: dividend • #2 exp, #3 man: divisor • #4 signed integer in 0…255: precision Pushed: • #0 exp, #1 man = #0.1old ÷ #2.3old float reciprocal, precision embedded u8_10100_0111 float reciprocal, precision in register 08_10100_0111 Pulled: • #0 exp, #1 man: operand Pushed: • #0 exp, #1 man = 1 ÷ #0.1old If u8 is zero, FD_1R is performed instead. Pulled: • #0 exp, #1 man: operand • #3 signed integer in 0…255: precision Pushed: • #0 exp, #1 man = 1 ÷ #0.1old float multiply and add, precision embedded u8_01100_0111 float multiply and add, precision in register 08_01100_0111 Pulled: • #0 exp, #1 man: multiplicand • #2 exp, #3 man: multiplier • #4 exp, #5 man: addend Pushed: • #0 exp, #1 man = (#0.1old × #2.3old) + #4.5old If u8 is zero, FMA_R is performed instead. Pulled: • #0 exp, #1 man: multiplicand • #2 exp, #3 man: multiplier • #4 exp, #5 man: addend • #6 signed integer in 0…255: precision Pushed: • #0 exp, #1 man = (#0.1old × #2.3old) + #4.5old float multiply and subtract, precision embedded u8_11100_0111 float multiply and subtract, precision in register 08_11100_0111 Pulled: • #0 exp, #1 man: multiplicand • #2 exp, #3 man: multiplier • #4 exp, #5 man: addend Pushed: • #0 exp, #1 man = (#0.1old × #2.3old) − #4.5old If u8 is zero, FMS_R is performed instead. Pulled: • #0 exp, #1 man: multiplicand • #2 exp, #3 man: multiplier • #4 exp, #5 man: addend • #6 signed integer in 0…255: precision Pushed: • #0 exp, #1 man = (#0.1old × #2.3old) − #4.5old

Integer-style division of floats. The remaining division operations are similar to those for integers. They involves two inputs (numerator N and denominator D) and two outputs (quotient Q and remainder R).

Here are the specifications:

• If D = 0, the operation will fail.
• NR will equal Q × D.
• The magnitude of R will be less than the magnitude of D.
• R will be of the same sign (positive, negative, zero) as D.
• N, D and R are floats, but Q is an integer.

Whatever the signs of N and D, Q is rounded toward negative infinity; no attempt is made to round Q to the nearest integer. Not observed is the usual float rounding rule, round-nearest-half-even.

Q will be trimmed as any other integer. The requested precision affects only R.

Another way to look at the operation is this:

• If the exponents of N and D are both nonnegative, then they are both mathematical integers, and the definition of Q are R is exactly as that of integers. Although R will be a mathematical integer, it will be stored as a float.
• If N or D has a negative exponent, both of them are multiplied by such a power of two as to make the exponents nonnegative. Then Q are R are figured as for integers. While Q will need no adjustment, R must be divided by the power of two that was earlier used for multiplication.

A result is null if either input is null, or if there is division by zero.

FIL is a rough guide to the magnitude of a float. The result is signed integer n if the float's absolute value is at least 2**n, but less than 2**(n + 1). It is easy for the machine to calculate. Define the leader of a positive integer as the address (within the register) of its rightmost nonzero bit. The leader of a negative integer is the leader of its absolute value, and the leader of zero or null is undefined. Then, for a float that is neither null nor zero, the result is obtained by adding the exponent to the mantissa's leader.

FR_E FR_R FQ_RE FQ_RR float remainder, precision embedded u8_00010_0111 float remainder, precision in register 08_00010_0111 Pulled: • #0 exp, #1 man: numerator • #2 exp, #3 man: denominator Pushed: • #0 exp, #1 man = remainder of #0.1old ÷ #2.3old If u8 is zero, FR_R is performed instead. Pulled: • #0 exp, #1 man: numerator • #2 exp, #3 man: denominator • #4 signed integer: precision Pushed: • #0 exp, #1 man = remainder of #0.1old ÷ #2.3old float quotient and remainder, precision embedded u8_10010_0111 float quotient and remainder, precision in register 08_10010_0111 Pulled: • #0 exp, #1 man: numerator • #2 exp, #3 man: denominator Pushed: • #0 exp, #1 man = remainder of #0.1old ÷ #2.3old • #2 signed integer = quotient of #0.1old ÷ #2.3old If u8 is zero, FQ_RR is performed instead. Pulled: • #0 exp, #1 man: numerator • #2 exp, #3 man: denominator • #4 signed integer in 0…255: precision Pushed: • #0 exp, #1 man = remainder of #0.1old ÷ #2.3old • #2 signed integer = quotient of #0.1old ÷ #2.3old float quotient ?_x_10111_0111 float integer logarithm ?_x_10111_0111 Pulled: • #0 exp, #1 man: numerator • #2 exp, #3 man: denominator Pushed: • #0 signed integer = quotient of #0.1old ÷ #2.3old Pulled: • #0 exp, #1 man: operand Pushed: • #0 signed integer: base-2 logarithm of absolute value of #0.1old, rounded toward negative infinity #0new is null if #0.1old is null or zero.

Format. (see also integer) The first instructions round-nearest-half-even the operand to a requested precision. The result is normalized and trimmed.

The last two instructions change the formatting of a float, but not its value. A programmer who desires the mantissa or exponent to be trimmed to a non-minimal size will need to invoke the integer instructions directly.

FF_RE FF_RR FF_N FF_T float format round, precision embedded u8_01010_0111 float format round, precision in register 08_01010_0111 Pulled: • #0 exp, #1 man: operand Pushed: • #0 exp, #1 man = #0.1old rounded If u8 is zero, FF_RR is performed instead. Pulled: • #0 exp, #1 man: operand • #3 signed integer in 0…255: precision Pushed: • #0 exp, #1 man: = #0.1old rounded float format normalize ?_x_10111_0111 float format trim ?_x_10111_0111 Pulled: • #0 exp, #1 man: operand Pushed: • #0 exp, #1 man: #0.1old normalized Pulled: • #0 exp, #1 man: operand Pushed: • #0 exp, #1 man: each of #0old and #1old trimmed to its minimum size

Transcendental. The standard mathematical functions in the table below can be included on LT4335 implementations intended for scientific purposes. As compared to the other instruction tables, a condensed format has been used, because most of the operations are very similar to one another; the top row explains.

As usual, any null input ensures a null output.

FT…E FT…R Comments FT_R2E FT_R2R float transcendental , precision embedded u8_b5_0111 float transcendental , precision in register 08_b5_0111 Pulled: • #0 exp, #1 man: operand Pushed: • of #0.1old If u8 is zero, FT…R is performed instead. Pulled: • #0 exp, #1 man: operand • #3 signed integer in 0…255: precision Pushed: • of #0.1old flo tra square root, prec emb u8_00110_0111 flo tra square root, prec reg 08_00110_0111 If operand is less than zero, result will be null. flo tra cube root, prec emb u8_10110_0111 flo tra cube root, prec reg 08_10110_0111 flo tra exponential, prec emb u8_01110_0111 flo tra exponential, prec reg 08_01110_0111 flo tra logarithm, prec emb u8_11110_0111 flo tra logarithm, prec reg 08_11110_0111 If operand is not greater than zero, result will be null. flo tra circular sine, prec emb u8_00001_0111 flo tra circular sine, prec reg 08_00001_0111 flo tra hyperbolic sine, prec emb u8_10001_0111 flo tra hyperbolic sine, prec reg 08_10001_0111 flo tra inverse circular sine, prec emb u8_01001_0111 flo tra inverse circular sine, prec reg 08_01001_0111 If absolute value of operand is greater than one, result will be null. Otherwise, −π ÷ 2 ≤ result ≤ +π ÷ 2. flo tra inverse hyperbolic sine, prec emb u8_11001_0111 flo tra inverse hyperbolic sine, prec reg 08_11001_0111 flo tra circular cosine, prec emb u8_00101_0111 flo tra circular cosine, prec reg 08_00101_0111 flo tra hyperbolic cosine, prec emb u8_10101_0111 flo tra hyperbolic cosine, prec reg 08_10101_0111 flo tra inverse circular cosine, prec emb u8_01101_0111 flo tra inverse circular cosine, prec reg 08_01101_0111 If absolute value of operand is greater than one, result will be null. Otherwise, 0 ≤ result ≤ π. flo tra inverse hyperbolic cosine, prec emb u8_11101_0111 flo tra inverse hyperbolic cosine, prec reg 08_11101_0111 If operand is less than one, result will be null. flo tra circular tangent, prec emb u8_00011_0111 flo tra circular tangent, prec reg 08_00011_0111 If operand approximates an odd multiple of π ÷ 2, result will be null because of overflow. flo tra hyperbolic tangent, prec emb u8_10011_0111 flo tra hyperbolic tangent, prec reg 08_10011_0111 flo tra inverse circular tangent, one argument, prec emb u8_01011_0111 flo tra inverse circular tangent, one argument, prec reg 08_01011_0111 −π ÷ 2 < result < +π ÷ 2. flo tra inverse hyperbolic tangent, prec emb u8_11011_0111 flo tra inverse hyperbolic tangent, prec reg 08_11011_0111 If absolute value of operand is not less than one, result will be null. flo tra inverse circular tangent, two arguments, prec emb u8_00111_0111 flo tra inverse circular tangent, two arguments, prec reg 08_00111_0111 see note below Pulled: • #0 exp, #1 man: abscissa • #2 exp, #3 man: ordinate Pushed: • #0 exp, #1 man: result If u8 is zero, FA_ICT_2R is performed instead. Pulled: • #0 exp, #1 man: abscissa • #2 exp, #3 man: ordinate • #4 signed integer in 0…255: precision Pushed: • #0 exp, #1 man: result

Generally, FT_ICT_2E and FT_ICT_2R return the inverse circular tangent of ordinate ÷ abscissa. According to the signs of ordinate and abscissa, however, the result may be increased or decreased by 2 × π. Also, a nonnull result is obtained when the abscissa is zero if the ordinate is not zero. The effect is that of the widely used atan2 function found in many computer languages, with an overall range of −π < result ≤ +π. Here are the details:

if…then…
ordinate < 0 and abscissa < 0−π < result < −π ÷ 2
ordinate < 0 and abscissa = 0result = −π ÷ 2
ordinate < 0 and abscissa > 0−π ÷ 2 < result < 0
ordinate = 0 and abscissa > 0result = 0
ordinate > 0 and abscissa > 00 < result < +π ÷ 2
ordinate > 0 and abscissa = 0result = +π ÷ 2
ordinate > 0 and abscissa < 0+π ÷ 2 < result < +π
ordinate = 0 and abscissa < 0result = +π
ordinate = 0 and abscissa = 0result is null