This specification is not final and is subject to change. Use is subject to license terms.

Update to IEEE 754-2019 Terminology

Changes to the Java Virtual Machine Specification • Version 15-internal+0-adhoc.darcy.

This document describes changes to the Java Virtual Machine Specification in support of JDK-8240327 to use the floating-point terminology of IEEE 754-2019 rather than continuing to use the obsolete terminology of IEEE 754-1985.

This document includes, in Chapter 6, all the JVM instructions which consume or produce floating-point values. Most of these instructions are updated to use new floating-point terminology: instructions for load/store, arithmetic, and type conversion. A few instructions are not updated, such as those for object manipulation and method return, but are included for completeness, to show what has not changed.

Changes are described with respect to existing sections of the JLS. New text is indicated like this and deleted text is indicated like this. Explanation and discussion, as needed, is set aside in grey boxes.

Chapter 2: The Structure of the Java Virtual Machine

2.3 Primitive Types and Values

2.3.2 Floating-Point Types, Value Sets, and Values

The floating-point types are float and double, which are conceptually associated with the 32-bit single-precision binary32 and 64-bit double-precision binary64 format IEEE 754 values and operations as specified in IEEE Standard for Binary Floating-Point Arithmetic (ANSI/IEEE Std. 754-1985, 754-2019, New York).

In the 1985 edition of the IEEE 754 standard, the binary32 format was known as single and binary64 format was known as double.

The IEEE 754 standard includes not only positive and negative sign-magnitude numbers, but also positive and negative zeros, positive and negative infinities, and a special Not-a-Number value (hereafter abbreviated as "NaN"). The NaN value is used to represent the result of certain invalid operations such as dividing zero by zero.

Every implementation of the Java Virtual Machine is required to support two standard sets of floating-point values, called the float value set and the double value set. In addition, an implementation of the Java Virtual Machine may, at its option, support either or both of two extended-exponent floating-point value sets, called the float-extended-exponent value set and the double-extended-exponent value set. These extended-exponent value sets may, under certain circumstances, be used instead of the standard value sets to represent the values of type float or double.

The finite nonzero values of any floating-point value set can all be expressed in the form s m 2^(e\ −\ N +\ 1)^, where s is +1 or −1, m is a positive integer less than 2N, and e is an integer between Emin = −(2K−1−2) and Emax = 2K−1−1, inclusive, and where N and K are parameters that depend on the value set. Some values can be represented in this form in more than one way; for example, supposing that a value v in a value set might be represented in this form using certain values for s, m, and e, then if it happened that m were even and e were less than 2K-1, one could halve m and increase e by 1 to produce a second representation for the same value v. A representation in this form is called normalized if m 2N-1; otherwise the representation is said to be denormalized. subnormal. If a value in a value set cannot be represented in such a way that m 2N-1, then the value is said to be a denormalized subnormal value, because it has no its magnitude is below the magnitude of the smallest normalized representation. value in the format.

The constraints on the parameters N and K (and on the derived parameters Emin and Emax) for the two required and two optional floating-point value sets are summarized in Table 2.3.2-A.

::: {.table #jvms-2.3.2-140-A}

Table 2.3.2-A. Floating-point value set parameters

::
Parameter float float-extended-exponent double double-extended-exponent
N 24 24 53 53
K 8 11 11 15
Emax +127 +1023 +1023 +16383
Emin -126 -1022 -1022 -16382

Where one or both extended-exponent value sets are supported by an implementation, then for each supported extended-exponent value set there is a specific implementation-dependent constant K, whose value is constrained by Table 2.3.2-A; this value K in turn dictates the values for Emin and Emax.

Each of the four value sets includes not only the finite nonzero values that are ascribed to it above, but also the five values positive zero, negative zero, positive infinity, negative infinity, and NaN.

Note that the constraints in Table 2.3.2-A are designed so that every element of the float value set is necessarily also an element of the float-extended-exponent value set, the double value set, and the double-extended-exponent value set. Likewise, each element of the double value set is necessarily also an element of the double-extended-exponent value set. Each extended-exponent value set has a larger range of exponent values than the corresponding standard value set, but does not have more precision.

The elements of the float value set are exactly the values that can be represented using the single binary32 floating-point format defined in the IEEE 754 standard, except that there is only one NaN value (IEEE 754 specifies 224-2 distinct NaN values). The elements of the double value set are exactly the values that can be represented using the double binary64 floating-point format defined in the IEEE 754 standard, except that there is only one NaN value (IEEE 754 specifies 253-2 distinct NaN values). Note, however, that the elements of the float-extended-exponent and double-extended-exponent value sets defined here do not correspond to the values that can be represented using IEEE 754 single binary32 extended and double binary64 extended formats, respectively. This specification does not mandate a specific representation for the values of the floating-point value sets except where floating-point values must be represented in the class file format (4.4.4, 4.4.5).

The float, float-extended-exponent, double, and double-extended-exponent value sets are not types. It is always correct for an implementation of the Java Virtual Machine to use an element of the float value set to represent a value of type float; however, it may be permissible in certain contexts for an implementation to use an element of the float-extended-exponent value set instead. Similarly, it is always correct for an implementation to use an element of the double value set to represent a value of type double; however, it may be permissible in certain contexts for an implementation to use an element of the double-extended-exponent value set instead.

Except for NaNs, values of the floating-point value sets are ordered. When arranged from smallest to largest, they are negative infinity, negative finite values, positive and negative zero, positive finite values, and positive infinity.

Floating-point positive zero and floating-point negative zero compare as equal, but there are other operations that can distinguish them; for example, dividing 1.0 by 0.0 produces positive infinity, but dividing 1.0 by -0.0 produces negative infinity.

NaNs are unordered, so numerical comparisons and tests for numerical equality have the value false if either or both of their operands are NaN. In particular, a test for numerical equality of a value against itself has the value false if and only if the value is NaN. A test for numerical inequality has the value true if either operand is NaN.

2.8 Floating-Point Arithmetic

The Java Virtual Machine incorporates a subset of the floating-point arithmetic specified in IEEE Standard for Binary Floating-Point Arithmetic (ANSI/IEEE Std. 754-19852019, New York).

Versions of the Java Virtual Machine prior to Java SE 15 used the 1985 edition of the IEEE 754 floating-point standard. An upgrade to the 2019 edition of the IEEE 754 standard occurred in Java SE 15. In the 1985 edition of the IEEE 754 standard, the binary32 format was known as single and binary64 format was known as double.

Java Virtual Machine operations on floating-point numbers behave as specified in IEEE 754, with the exception of the remainder instructions (6.5.drem, 6.5.frem). In particular, the Java Virtual Machine requires full support of IEEE 754 subnormal floating-point numbers and gradual underflow, which make it easier to prove desirable properties of particular numerical algorithms.

Floating-point arithmetic is an approximation to real arithmetic. While there are an infinite number of real numbers, a particular floating-point format only has a finite number of values. A rounding policy is a function used in floating-point arithmetic to map from a real number to a floating-point value in a format. For real numbers in the representable range of a floating-point format, a continuous segment of the real number line is mapped to a single floating-point value. The real number whose value is numerically equal to a floating-point value is mapped to that floating-point value. For example, the real number 1.5 gets mapped to the floating-point value 1.5 in a given format.

The Java virtual machine defines two rounding policies, as follows:

The Java Virtual Machine requires that floating-point arithmetic behave as if every floating-point operation rounded its floating-point result to the result precision. The rounding policy used for the arithmetic operations is round to nearest, except for converting a floating-point value to an integer and remainder where round toward zero is used instead.

The Java Virtual Machine's floating-point operators do not throw run-time exceptions (not to be confused with IEEE 754 floating-point exceptions). An operation that overflows produces a signed infinity, an operation that underflows produces a subnormal value or a signed zero, and an operation that has no unique mathematically defined result produces NaN. All numeric operations with NaN as an operand produce NaN as a result.**

2.8.1 Java Virtual Machine Floating-Point Arithmetic and IEEE 754

The key differences between the floating-point arithmetic supported by the Java Virtual Machine and the IEEE 754 standard are:

2.8.2 Floating-Point Modes

Every method has a floating-point mode, which is either FP-strict or not FP-strict. The floating-point mode of a method is determined by the setting of the ACC_STRICT flag of the access_flags item of the method_info structure (4.6) defining the method. A method for which this flag is set is FP-strict; otherwise, the method is not FP-strict.

Note that this mapping of the ACC_STRICT flag implies that methods in classes compiled by a compiler in JDK release 1.1 or earlier are effectively not FP-strict.

We will refer to an operand stack as having a given floating-point mode when the method whose invocation created the frame containing the operand stack has that floating-point mode. Similarly, we will refer to a Java Virtual Machine instruction as having a given floating-point mode when the method containing that instruction has that floating-point mode.

If a float-extended-exponent value set is supported (2.3.2), values of type float on an operand stack that is not FP-strict may range over that value set except where prohibited by value set conversion (2.8.3). If a double-extended-exponent value set is supported (2.3.2), values of type double on an operand stack that is not FP-strict may range over that value set except where prohibited by value set conversion.

In all other contexts, whether on the operand stack or elsewhere, and regardless of floating-point mode, floating-point values of type float and double may only range over the float value set and double value set, respectively. In particular, class and instance fields, array elements, local variables, and method parameters may only contain values drawn from the standard value sets.

2.8.3 Value Set Conversion

An implementation of the Java Virtual Machine that supports an extended floating-point value set is permitted or required, under specified circumstances, to map a value of the associated floating-point type between the extended and the standard value sets. Such a value set conversion is not a type conversion, but a mapping between the value sets associated with the same type.

Where value set conversion is indicated, an implementation is permitted to perform one of the following operations on a value:

In addition, where value set conversion is indicated, certain operations are required:

Such required value set conversions may occur as a result of passing a parameter of a floating-point type during method invocation, including native method invocation; returning a value of a floating-point type from a method that is not FP-strict to a method that is FP-strict; or storing a value of a floating-point type into a local variable, a field, or an array in a method that is not FP-strict.

Not all values from an extended-exponent value set can be mapped exactly to a value in the corresponding standard value set. If a value being mapped is too large to be represented exactly (its exponent is greater than that permitted by the standard value set), it is converted to a (positive or negative) infinity of the corresponding type. If a value being mapped is too small to be represented exactly (its exponent is smaller than that permitted by the standard value set), it is rounded to the nearest of a representable denormalized subnormal value or zero of the same sign.

Value set conversion preserves infinities and NaNs and cannot change the sign of the value being converted. Value set conversion has no effect on a value that is not of a floating-point type.

2.11 Instruction Set Summary

A Java Virtual Machine instruction consists of a one-byte opcode specifying the operation to be performed, followed by zero or more operands supplying arguments or data that are used by the operation. Many instructions have no operands and consist only of an opcode.

Ignoring exceptions, the inner loop of a Java Virtual Machine interpreter is effectively

do {
    atomically calculate pc and fetch opcode at pc;
    if (operands) fetch operands;
    execute the action for the opcode;
} while (there is more to do);

The number and size of the operands are determined by the opcode. If an operand is more than one byte in size, then it is stored in big-endian order - high-order byte first. For example, an unsigned 16-bit index into the local variables is stored as two unsigned bytes, byte1 and byte2, such that its value is (byte1 << 8) | byte2.

The bytecode instruction stream is only single-byte aligned. The two exceptions are the lookupswitch and tableswitch instructions ([6.5.lookupswitch], [6.5.tableswitch]), which are padded to force internal alignment of some of their operands on 4-byte boundaries.

The decision to limit the Java Virtual Machine opcode to a byte and to forgo data alignment within compiled code reflects a conscious bias in favor of compactness, possibly at the cost of some performance in naive implementations. A one-byte opcode also limits the size of the instruction set. Not assuming data alignment means that immediate data larger than a byte must be constructed from bytes at run time on many machines.

2.11.1 Types and the Java Virtual Machine

Most of the instructions in the Java Virtual Machine instruction set encode type information about the operations they perform. For instance, the iload instruction (6.5.iload) loads the contents of a local variable, which must be an int, onto the operand stack. The fload instruction (6.5.fload) does the same with a float value. The two instructions may have identical implementations, but have distinct opcodes.

For the majority of typed instructions, the instruction type is represented explicitly in the opcode mnemonic by a letter: i for an int operation, l for long, s for short, b for byte, c for char, f for float, d for double, and a for reference. Some instructions for which the type is unambiguous do not have a type letter in their mnemonic. For instance, arraylength always operates on an object that is an array. Some instructions, such as goto, an unconditional control transfer, do not operate on typed operands.

Given the Java Virtual Machine's one-byte opcode size, encoding types into opcodes places pressure on the design of its instruction set. If each typed instruction supported all of the Java Virtual Machine's run-time data types, there would be more instructions than could be represented in a byte. Instead, the instruction set of the Java Virtual Machine provides a reduced level of type support for certain operations. In other words, the instruction set is intentionally not orthogonal. Separate instructions can be used to convert between unsupported and supported data types as necessary.

[Table 2.11.1-A] summarizes the type support in the instruction set of the Java Virtual Machine. A specific instruction, with type information, is built by replacing the T in the instruction template in the opcode column by the letter in the type column. If the type column for some instruction template and type is blank, then no instruction exists supporting that type of operation. For instance, there is a load instruction for type int, iload, but there is no load instruction for type byte.

Note that most instructions in [Table 2.11.1-A] do not have forms for the integral types byte, char, and short. None have forms for the boolean type. A compiler encodes loads of literal values of types byte and short using Java Virtual Machine instructions that sign-extend those values to values of type int at compile-time or run-time. Loads of literal values of types boolean and char are encoded using instructions that zero-extend the literal to a value of type int at compile-time or run-time. Likewise, loads from arrays of values of type boolean, byte, short, and char are encoded using Java Virtual Machine instructions that sign-extend or zero-extend the values to values of type int. Thus, most operations on values of actual types boolean, byte, char, and short are correctly performed by instructions operating on values of computational type int.

::: {.table #jvms-2.11.1-220}

Table 2.11.1-A. Type support in the Java Virtual Machine instruction set

::
opcode byte short int long float double char reference
Tipush bipush sipush
Tconst iconst lconst fconst dconst aconst
Tload iload lload fload dload aload
Tstore istore lstore fstore dstore astore
Tinc iinc
Taload baload saload iaload laload faload daload caload aaload
Tastore bastore sastore iastore lastore fastore dastore castore aastore
Tadd iadd ladd fadd dadd
Tsub isub lsub fsub dsub
Tmul imul lmul fmul dmul
Tdiv idiv ldiv fdiv ddiv
Trem irem lrem frem drem
Tneg ineg lneg fneg dneg
Tshl ishl lshl
Tshr ishr lshr
Tushr iushr lushr
Tand iand land
Tor ior lor
Txor ixor lxor
i2T i2b i2s i2l i2f i2d
l2T l2i l2f l2d
f2T f2i f2l f2d
d2T d2i d2l d2f
Tcmp lcmp
Tcmpl fcmpl dcmpl
Tcmpg fcmpg dcmpg
if_TcmpOP if_icmpOP if_acmpOP
Treturn ireturn lreturn freturn dreturn areturn

The mapping between Java Virtual Machine actual types and Java Virtual Machine computational types is summarized by [Table 2.11.1-B].

Certain Java Virtual Machine instructions such as pop and swap operate on the operand stack without regard to type; however, such instructions are constrained to use only on values of certain categories of computational types, also given in [Table 2.11.1-B].

::: {.table #jvms-2.11.1-320}

Table 2.11.1-B. Actual and Computational types in the Java Virtual Machine

::
Actual type Computational type Category
boolean int 1
byte int 1
char int 1
short int 1
int int 1
float float 1
reference reference 1
returnAddress returnAddress 1
long long 2
double double 2

2.11.2 Load and Store Instructions

The load and store instructions transfer values between the local variables (2.6.1) and the operand stack (2.6.2) of a Java Virtual Machine frame (2.6):

Instructions that access fields of objects and elements of arrays ([2.11.5]) also transfer data to and from the operand stack.

Instruction mnemonics shown above with trailing letters between angle brackets (for instance, iload_<n>) denote families of instructions (with members iload_0, iload_1, iload_2, and iload_3 in the case of iload_<n>). Such families of instructions are specializations of an additional generic instruction (iload) that takes one operand. For the specialized instructions, the operand is implicit and does not need to be stored or fetched. The semantics are otherwise the same (iload_0 means the same thing as iload with the operand 0). The letter between the angle brackets specifies the type of the implicit operand for that family of instructions: for <n>, a nonnegative integer; for <i>, an int; for <l>, a long; for <f>, a float; and for <d>, a double. Forms for type int are used in many cases to perform operations on values of type byte, char, and short (2.11.1).

This notation for instruction families is used throughout this specification.

2.11.3 Arithmetic Instructions

The arithmetic instructions compute a result that is typically a function of two values on the operand stack, pushing the result back on the operand stack. There are two main kinds of arithmetic instructions: those operating on integer values and those operating on floating-point values. Within each of these kinds, the arithmetic instructions are specialized to Java Virtual Machine numeric types. There is no direct support for integer arithmetic on values of the byte, short, and char types (2.11.1), or for values of the boolean type; those operations are handled by instructions operating on type int. Integer and floating-point instructions also differ in their behavior on overflow and divide-by-zero. The arithmetic instructions are as follows:

The semantics of the Java programming language operators on integer and floating-point values (JLS §4.2.2, JLS §4.2.4) are directly supported by the semantics of the Java Virtual Machine instruction set.

The Java Virtual Machine does not indicate overflow during operations on integer data types. The only integer operations that can throw an exception are the integer divide instructions (idiv and ldiv) and the integer remainder instructions (irem and lrem), which throw an ArithmeticException if the divisor is zero.

Java Virtual Machine operations on floating-point numbers behave as specified in IEEE 754. In particular, the Java Virtual Machine requires full support of IEEE 754 denormalized floating-point numbers and gradual underflow, which make it easier to prove desirable properties of particular numerical algorithms.

The Java Virtual Machine requires that floating-point arithmetic behave as if every floating-point operator rounded its floating-point result to the result precision. Inexact results must be rounded to the representable value nearest to the infinitely precise result; if the two nearest representable values are equally near, the one having a least significant bit of zero is chosen. This is the IEEE 754 standard's default rounding mode, known as round to nearest mode.

The Java Virtual Machine uses the IEEE 754 round towards zero mode when converting a floating-point value to an integer. This results in the number being truncated; any bits of the significand that represent the fractional part of the operand value are discarded. Round towards zero mode chooses as its result the type's value closest to, but no greater in magnitude than, the infinitely precise result.

The Java Virtual Machine's floating-point operators do Machine does not throw run-time exceptions (not to be confused with IEEE 754 for floating-point operations. The detailed behavior of floating-point exceptions). An operation that overflows produces a signed infinity, an operation that underflows produces a denormalized value or a signed zero, and an operation that has no mathematically definite result produces NaN. All numeric operations with NaN as an operand produce NaN as a result. on overflow and underflow conditions is discussed elsewhere (2.8).

Comparisons on values of type long (lcmp) perform a signed comparison. Comparisons on values of floating-point types (dcmpg, dcmpl, fcmpg, fcmpl) are performed using IEEE 754 nonsignaling comparisons.

2.11.4 Type Conversion Instructions

The type conversion instructions allow conversion between Java Virtual Machine numeric types. These may be used to implement explicit conversions in user code or to mitigate the lack of orthogonality in the instruction set of the Java Virtual Machine.

The Java Virtual Machine directly supports the following widening numeric conversions:

The widening numeric conversion instructions are i2l, i2f, i2d, l2f, l2d, and f2d. The mnemonics for these opcodes are straightforward given the naming conventions for typed instructions and the punning use of 2 to mean "to." For instance, the i2d instruction converts an int value to a double.

Most widening numeric conversions do not lose information about the overall magnitude of a numeric value. Indeed, conversions widening from int to long and int to double do not lose any information at all; the numeric value is preserved exactly. Conversions widening from float to double that are FP-strict (2.8.2) also preserve the numeric value exactly; only such conversions that are not FP-strict may lose information about the overall magnitude of the converted value.

Conversions from int to float, or from long to float, or from long to double, may lose precision, that is, may lose some of the least significant bits of the value; the resulting floating-point value is a correctly rounded version of the integer value, using IEEE 754 round to nearest mode.

Despite the fact that loss of precision may occur, widening numeric conversions never cause the Java Virtual Machine to throw a run-time exception (not to be confused with an IEEE 754 floating-point exception).

A widening numeric conversion of an int to a long simply sign-extends the two's-complement representation of the int value to fill the wider format. A widening numeric conversion of a char to an integral type zero-extends the representation of the char value to fill the wider format.

Note that widening numeric conversions do not exist from integral types byte, char, and short to type int. As noted in 2.11.1, values of type byte, char, and short are internally widened to type int, making these conversions implicit.

The Java Virtual Machine also directly supports the following narrowing numeric conversions:

The narrowing numeric conversion instructions are i2b, i2c, i2s, l2i, f2i, f2l, d2i, d2l, and d2f. A narrowing numeric conversion can result in a value of different sign, a different order of magnitude, or both; it may thereby lose precision.

A narrowing numeric conversion of an int or long to an integral type T simply discards all but the n lowest-order bits, where n is the number of bits used to represent type T. This may cause the resulting value not to have the same sign as the input value.

In a narrowing numeric conversion of a floating-point value to an integral type T, where T is either int or long, the floating-point value is converted as follows:

A narrowing numeric conversion from double to float behaves in accordance with IEEE 754. The result is correctly rounded using IEEE 754 round to nearest modethe round to nearest rounding policy. A value too small to be represented as a float is converted to a positive or negative zero of type float; a value too large to be represented as a float is converted to a positive or negative infinity. A double NaN is always converted to a float NaN.

Despite the fact that overflow, underflow, or loss of precision may occur, narrowing conversions among numeric types never cause the Java Virtual Machine to throw a run-time exception (not to be confused with an IEEE 754 floating-point exception).

Chapter 4: The class File Format

4.4 The Constant Pool

4.4.4 The CONSTANT_Integer_info and CONSTANT_Float_info Structures

The CONSTANT_Integer_info and CONSTANT_Float_info structures represent 4-byte numeric (int and float) constants:

CONSTANT_Integer_info {
    u1 tag;
    u4 bytes;
}

CONSTANT_Float_info {
    u1 tag;
    u4 bytes;
}

The items of these structures are as follows:

tag

The tag item of the CONSTANT_Integer_info structure has the value CONSTANT_Integer (3).

The tag item of the CONSTANT_Float_info structure has the value CONSTANT_Float (4).

bytes

The bytes item of the CONSTANT_Integer_info structure represents the value of the int constant. The bytes of the value are stored in big-endian (high byte first) order.

The bytes item of the CONSTANT_Float_info structure represents the value of the float constant in IEEE 754 floating-point single binary32 format (2.3.2). The bytes of the single format representation are stored in big-endian (high byte first) order.

The value represented by the CONSTANT_Float_info structure is determined as follows. The bytes of the value are first converted into an int constant bits. Then:

  • If bits is 0x7f800000, the float value will be positive infinity.

  • If bits is 0xff800000, the float value will be negative infinity.

  • If bits is in the range 0x7f800001 through 0x7fffffff or in the range 0xff800001 through 0xffffffff, the float value will be NaN.

  • In all other cases, let s, e, and m be three values that might be computed from bits:

    int s = ((*bits* >> 31) == 0) ? 1 : -1;
    int e = ((*bits* >> 23) & 0xff);
    int m = (e == 0) ?
              (*bits* & 0x7fffff) << 1 :
              (*bits* & 0x7fffff) | 0x800000;

Then the float value equals the result of the mathematical expression s · m · 2e-150.

4.4.5 The CONSTANT_Long_info and CONSTANT_Double_info Structures

The CONSTANT_Long_info and CONSTANT_Double_info represent 8-byte numeric (long and double) constants:

CONSTANT_Long_info {
    u1 tag;
    u4 high_bytes;
    u4 low_bytes;
}

CONSTANT_Double_info {
    u1 tag;
    u4 high_bytes;
    u4 low_bytes;
}

All 8-byte constants take up two entries in the constant_pool table of the class file. If a CONSTANT_Long_info or CONSTANT_Double_info structure is the entry at index n in the constant_pool table, then the next usable entry in the table is located at index n+2. The constant_pool index n+1 must be valid but is considered unusable.

In retrospect, making 8-byte constants take two constant pool entries was a poor choice.

The items of these structures are as follows:

tag

The tag item of the CONSTANT_Long_info structure has the value CONSTANT_Long (5).

The tag item of the CONSTANT_Double_info structure has the value CONSTANT_Double (6).

high_bytes, low_bytes

The unsigned high_bytes and low_bytes items of the CONSTANT_Long_info structure together represent the value of the long constant

((long) high_bytes << 32) + low_bytes

where the bytes of each of high_bytes and low_bytes are stored in big-endian (high byte first) order.

The high_bytes and low_bytes items of the CONSTANT_Double_info structure together represent the double value in IEEE 754 floating-point double binary64 format (2.3.2). The bytes of each item are stored in big-endian (high byte first) order.

The value represented by the CONSTANT_Double_info structure is determined as follows. The high_bytes and low_bytes items are converted into the long constant bits, which is equal to

((long) high_bytes << 32) + low_bytes

Then:

  • If bits is 0x7ff0000000000000L, the double value will be positive infinity.

  • If bits is 0xfff0000000000000L, the double value will be negative infinity.

  • If bits is in the range 0x7ff0000000000001L through 0x7fffffffffffffffL or in the range 0xfff0000000000001L through 0xffffffffffffffffL, the double value will be NaN.

  • In all other cases, let s, e, and m be three values that might be computed from bits:

    int s = ((*bits* >> 63) == 0) ? 1 : -1;
    int e = (int)((*bits* >> 52) & 0x7ffL);
    long m = (e == 0) ?
               (*bits* & 0xfffffffffffffL) << 1 :
               (*bits* & 0xfffffffffffffL) | 0x10000000000000L;

Then the floating-point value equals the double value of the mathematical expression s · m · 2e-1075.

Chapter 6: The Java Virtual Machine Instruction Set

6.5 Instructions

d2f

Operation

Convert double to float

Format

d2f

Forms

d2f = 144 (0x90)

Operand Stack

..., value

..., result

Description

The value on the top of the operand stack must be of type double. It is popped from the operand stack and undergoes value set conversion (2.8.3) resulting in value'. Then value' is converted to a float result using IEEE 754 the round to nearest mode. rounding policy (2.8). The result is pushed onto the operand stack.

Where an d2f instruction is FP-strict (2.8.2), the result of the conversion is always rounded to the nearest representable value in the float value set (2.3.2).

Where an d2f instruction is not FP-strict, the result of the conversion may be taken from the float-extended-exponent value set (2.3.2); it is not necessarily rounded to the nearest representable value in the float value set.

A finite value' too small to be represented as a float is converted to a zero of the same sign; a finite value' too large to be represented as a float is converted to an infinity of the same sign. A double NaN is converted to a float NaN.

Notes

The d2f instruction performs a narrowing primitive conversion (JLS §5.1.3). It may lose information about the overall magnitude of value' and may also lose precision.

d2i

Operation

Convert double to int

Format

d2i

Forms

d2i = 142 (0x8e)

Operand Stack

..., value

..., result

Description

The value on the top of the operand stack must be of type double. It is popped from the operand stack and undergoes value set conversion (2.8.3) resulting in value'. Then value' is converted to an int. The result is pushed onto the operand stack:

  • If the value' is NaN, the result of the conversion is an int 0.

  • Otherwise, if the value' is not an infinity, it is rounded to an integer value V, rounding towards zero V using IEEE 754 the round towards toward zero mode. rounding policy (2.8). If this integer value V can be represented as an int, then the result is the int value V.

  • Otherwise, either the value' must be too small (a negative value of large magnitude or negative infinity), and the result is the smallest representable value of type int, or the value' must be too large (a positive value of large magnitude or positive infinity), and the result is the largest representable value of type int.

Notes

The d2i instruction performs a narrowing primitive conversion (JLS §5.1.3). It may lose information about the overall magnitude of value' and may also lose precision.

d2l

Operation

Convert double to long

Format

d2l

Forms

d2l = 143 (0x8f)

Operand Stack

..., value

..., result

Description

The value on the top of the operand stack must be of type double. It is popped from the operand stack and undergoes value set conversion (2.8.3) resulting in value'. Then value' is converted to a long. The result is pushed onto the operand stack:

  • If the value' is NaN, the result of the conversion is a long 0.

  • Otherwise, if the value' is not an infinity, it is rounded to an integer value V, rounding towards zero V using IEEE 754 the round towards toward zero mode. rounding policy (2.8). If this integer value V can be represented as a long, then the result is the long value V.

  • Otherwise, either the value' must be too small (a negative value of large magnitude or negative infinity), and the result is the smallest representable value of type long, or the value' must be too large (a positive value of large magnitude or positive infinity), and the result is the largest representable value of type long.

Notes

The d2l instruction performs a narrowing primitive conversion (JLS §5.1.3). It may lose information about the overall magnitude of value' and may also lose precision.

dadd

Operation

Add double

Format

dadd

Forms

dadd = 99 (0x63)

Operand Stack

..., value1, value2

..., result

Description

Both value1 and value2 must be of type double. The values are popped from the operand stack and undergo value set conversion (2.8.3), resulting in value1' and value2'. The double result is value1' + value2'. The result is pushed onto the operand stack.

The result of a dadd instruction is governed by the rules of IEEE 754 arithmetic:

  • If either value1' or value2' is NaN, the result is NaN.

  • The sum of two infinities of opposite sign is NaN.

  • The sum of two infinities of the same sign is the infinity of that sign.

  • The sum of an infinity and any finite value is equal to the infinity.

  • The sum of two zeroes of opposite sign is positive zero.

  • The sum of two zeroes of the same sign is the zero of that sign.

  • The sum of a zero and a nonzero finite value is equal to the nonzero value.

  • The sum of two nonzero finite values of the same magnitude and opposite sign is positive zero.

  • In the remaining cases, where neither operand is an infinity, a zero, or NaN and the values have the same sign or have different magnitudes, the sum is computed and rounded to the nearest representable value using IEEE 754 the round to nearest mode. rounding policy. If the magnitude is too large to represent as a double, we say the operation overflows; the result is then an infinity of appropriate sign. If the magnitude is too small to represent as a double, we say the operation underflows; the result is then a zero of appropriate sign.

The Java Virtual Machine requires support of gradual underflow as defined by IEEE 754. (2.8). Despite the fact that overflow, underflow, or loss of precision may occur, execution of a dadd instruction never throws a run-time exception.

daload

Operation

Load double from array

Format

daload

Forms

daload = 49 (0x31)

Operand Stack

..., arrayref, index

..., value

Description

The arrayref must be of type reference and must refer to an array whose components are of type double. The index must be of type int. Both arrayref and index are popped from the operand stack. The double value in the component of the array at index is retrieved and pushed onto the operand stack.

Run-time Exceptions

If arrayref is null, daload throws a NullPointerException.

Otherwise, if index is not within the bounds of the array referenced by arrayref, the daload instruction throws an ArrayIndexOutOfBoundsException.

dastore

Operation

Store into double array

Format

dastore

Forms

dastore = 82 (0x52)

Operand Stack

..., arrayref, index, value

...

Description

The arrayref must be of type reference and must refer to an array whose components are of type double. The index must be of type int, and value must be of type double. The arrayref, index, and value are popped from the operand stack. The double value undergoes value set conversion (2.8.3), resulting in value', which is stored as the component of the array indexed by index.

Run-time Exceptions

If arrayref is null, dastore throws a NullPointerException.

Otherwise, if index is not within the bounds of the array referenced by arrayref, the dastore instruction throws an ArrayIndexOutOfBoundsException.

dcmp<op>

Operation

Compare double

Format

dcmp<op>

Forms

dcmpg = 152 (0x98)

dcmpl = 151 (0x97)

Operand Stack

..., value1, value2

..., result

Description

Both value1 and value2 must be of type double. The values are popped from the operand stack and undergo value set conversion (2.8.3), resulting in value1' and value2'. A floating-point comparison is performed:

  • If value1' is greater than value2', the int value 1 is pushed onto the operand stack.

  • Otherwise, if value1' is equal to value2', the int value 0 is pushed onto the operand stack.

  • Otherwise, if value1' is less than value2', the int value -1 is pushed onto the operand stack.

  • Otherwise, at least one of value1' or value2' is NaN. The dcmpg instruction pushes the int value 1 onto the operand stack and the dcmpl instruction pushes the int value -1 onto the operand stack.

Floating-point comparison is performed in accordance with IEEE 754. All values other than NaN are ordered, with negative infinity less than all finite values and positive infinity greater than all finite values. Positive zero and negative zero are considered equal.

Notes

The dcmpg and dcmpl instructions differ only in their treatment of a comparison involving NaN. NaN is unordered, so any double comparison fails if either or both of its operands are NaN. With both dcmpg and dcmpl available, any double comparison may be compiled to push the same result onto the operand stack whether the comparison fails on non-NaN values or fails because it encountered a NaN. For more information, see 3.5.

dconst_<d>

Operation

Push double

Format

dconst_<d>

Forms

dconst_0 = 14 (0xe)

dconst_1 = 15 (0xf)

Operand Stack

...

..., <d>

Description

Push the double constant <d> (0.0 or 1.0) onto the operand stack.

ddiv

Operation

Divide double

Format

ddiv

Forms

ddiv = 111 (0x6f)

Operand Stack

..., value1, value2

..., result

Description

Both value1 and value2 must be of type double. The values are popped from the operand stack and undergo value set conversion (2.8.3), resulting in value1' and value2'. The double result is value1' / value2'. The result is pushed onto the operand stack.

The result of a ddiv instruction is governed by the rules of IEEE 754 arithmetic:

  • If either value1' or value2' is NaN, the result is NaN.

  • If neither value1' nor value2' is NaN, the sign of the result is positive if both values have the same sign, negative if the values have different signs.

  • Division of an infinity by an infinity results in NaN.

  • Division of an infinity by a finite value results in a signed infinity, with the sign-producing rule just given.

  • Division of a finite value by an infinity results in a signed zero, with the sign-producing rule just given.

  • Division of a zero by a zero results in NaN; division of zero by any other finite value results in a signed zero, with the sign-producing rule just given.

  • Division of a nonzero finite value by a zero results in a signed infinity, with the sign-producing rule just given.

  • In the remaining cases, where neither operand is an infinity, a zero, or NaN, the quotient is computed and rounded to the nearest double using IEEE 754 the round to nearest mode. rounding policy. If the magnitude is too large to represent as a double, we say the operation overflows; the result is then an infinity of appropriate sign. If the magnitude is too small to represent as a double, we say the operation underflows; the result is then a zero of appropriate sign.

The Java Virtual Machine requires support of gradual underflow as defined by IEEE 754. (2.8). Despite the fact that overflow, underflow, division by zero, or loss of precision may occur, execution of a ddiv instruction never throws a run-time exception.

dload

Operation

Load double from local variable

Format

dload
index

Forms

dload = 24 (0x18)

Operand Stack

...

..., value

Description

The index is an unsigned byte. Both index and index+1 must be indices into the local variable array of the current frame (2.6). The local variable at index must contain a double. The value of the local variable at index is pushed onto the operand stack.

Notes

The dload opcode can be used in conjunction with the wide instruction (6.5.wide) to access a local variable using a two-byte unsigned index.

dload_<n>

Operation

Load double from local variable

Format

dload_<n>

Forms

dload_0 = 38 (0x26)

dload_1 = 39 (0x27)

dload_2 = 40 (0x28)

dload_3 = 41 (0x29)

Operand Stack

...

..., value

Description

Both <n> and <n>+1 must be indices into the local variable array of the current frame (2.6). The local variable at <n> must contain a double. The value of the local variable at <n> is pushed onto the operand stack.

Notes

Each of the dload_<n> instructions is the same as dload with an index of <n>, except that the operand <n> is implicit.

dmul

Operation

Multiply double

Format

dmul

Forms

dmul = 107 (0x6b)

Operand Stack

..., value1, value2

..., result

Description

Both value1 and value2 must be of type double. The values are popped from the operand stack and undergo value set conversion (2.8.3), resulting in value1' and value2'. The double result is value1' * value2'. The result is pushed onto the operand stack.

The result of a dmul instruction is governed by the rules of IEEE 754 arithmetic:

  • If either value1' or value2' is NaN, the result is NaN.

  • If neither value1' nor value2' is NaN, the sign of the result is positive if both values have the same sign and negative if the values have different signs.

  • Multiplication of an infinity by a zero results in NaN.

  • Multiplication of an infinity by a finite value results in a signed infinity, with the sign-producing rule just given.

  • In the remaining cases, where neither an infinity nor NaN is involved, the product is computed and rounded to the nearest representable value using IEEE 754 the round to nearest mode. rounding policy. If the magnitude is too large to represent as a double, we say the operation overflows; the result is then an infinity of appropriate sign. If the magnitude is too small to represent as a double, we say the operation underflows; the result is then a zero of appropriate sign.

The Java Virtual Machine requires support of gradual underflow as defined by IEEE 754. (2.8). Despite the fact that overflow, underflow, or loss of precision may occur, execution of a dmul instruction never throws a run-time exception.

dneg

Operation

Negate double

Format

dneg

Forms

dneg = 119 (0x77)

Operand Stack

..., value

..., result

Description

The value must be of type double. It is popped from the operand stack and undergoes value set conversion (2.8.3), resulting in value'. The double result is the arithmetic negation of value'. The result is pushed onto the operand stack.

For double values, negation is not the same as subtraction from zero. If x is +0.0, then 0.0-x equals +0.0, but -x equals -0.0. Unary minus merely inverts the sign of a double.

Special cases of interest:

  • If the operand is NaN, the result is NaN (recall that NaN has no sign).

  • If the operand is an infinity, the result is the infinity of opposite sign.

  • If the operand is a zero, the result is the zero of opposite sign.

drem

Operation

Remainder double

Format

drem

Forms

drem = 115 (0x73)

Operand Stack

..., value1, value2

..., result

Description

Both value1 and value2 must be of type double. The values are popped from the operand stack and undergo value set conversion (2.8.3), resulting in value1' and value2'. The result is calculated and pushed onto the operand stack as a double.

The result of a drem instruction is not the same as that of the so-calledthe remainder operation defined by IEEE 754 due to the choice of rounding policy (2.8). The IEEE 754 "remainder" operation computes the remainder from a an implied division using the round to nearest rounding policy ("rounding division"), not an implied division using the round toward zero rounding policy ("truncating division"), and so its behavior is not analogous to that of the usual integer remainder operator. Instead, the Java Virtual Machine defines drem to behave in a manner analogous to that of the Java Virtual Machine integer remainder instructions (irem and lrem); this may be compared with the C library function fmod.

The result of a drem instruction is governed by these rules, which match the rules for IEEE 754 remainder other than how the implied division is computed:

  • If either value1' or value2' is NaN, the result is NaN.

  • If neither value1' nor value2' is NaN, the sign of the result equals the sign of the dividend.

  • If the dividend is an infinity or the divisor is a zero or both, the result is NaN.

  • If the dividend is finite and the divisor is an infinity, the result equals the dividend.

  • If the dividend is a zero and the divisor is finite, the result equals the dividend.

  • In the remaining cases, where neither operand is an infinity, a zero, or NaN, the floating-point remainder result from a dividend value1' and a divisor value2' is defined by the mathematical relation result = value1' - (value2' * q), where q is an integer that is negative only if value1' / value2' is negative, and positive only if value1' / value2' is positive, and whose magnitude is as large as possible without exceeding the magnitude of the true mathematical quotient of value1' and value2'.

Despite the fact that division by zero may occur, evaluation of a drem instruction never throws a run-time exception. Overflow, underflow, or loss of precision cannot occur.

Notes

The IEEE 754 remainder operation may be computed by the library routine Math.IEEEremainder or StrictMath.IEEEremainder.

dreturn

Operation

Return double from method

Format

dreturn

Forms

dreturn = 175 (0xaf)

Operand Stack

..., value

[empty]

Description

The current method must have return type double. The value must be of type double. If the current method is a synchronized method, the monitor entered or reentered on invocation of the method is updated and possibly exited as if by execution of a monitorexit instruction (6.5.monitorexit) in the current thread. If no exception is thrown, value is popped from the operand stack of the current frame (2.6) and undergoes value set conversion (2.8.3), resulting in value'. The value' is pushed onto the operand stack of the frame of the invoker. Any other values on the operand stack of the current method are discarded.

The interpreter then returns control to the invoker of the method, reinstating the frame of the invoker.

Run-time Exceptions

If the Java Virtual Machine implementation does not enforce the rules on structured locking described in 2.11.10, then if the current method is a synchronized method and the current thread is not the owner of the monitor entered or reentered on invocation of the method, dreturn throws an IllegalMonitorStateException. This can happen, for example, if a synchronized method contains a monitorexit instruction, but no monitorenter instruction, on the object on which the method is synchronized.

Otherwise, if the Java Virtual Machine implementation enforces the rules on structured locking described in 2.11.10 and if the first of those rules is violated during invocation of the current method, then dreturn throws an IllegalMonitorStateException.

dstore

Operation

Store double into local variable

Format

dstore
index

Forms

dstore = 57 (0x39)

Operand Stack

..., value

...

Description

The index is an unsigned byte. Both index and index+1 must be indices into the local variable array of the current frame (2.6). The value on the top of the operand stack must be of type double. It is popped from the operand stack and undergoes value set conversion (2.8.3), resulting in value'. The local variables at index and index+1 are set to value'.

Notes

The dstore opcode can be used in conjunction with the wide instruction (6.5.wide) to access a local variable using a two-byte unsigned index.

dstore_<n>

Operation

Store double into local variable

Format

dstore_<n>

Forms

dstore_0 = 71 (0x47)

dstore_1 = 72 (0x48)

dstore_2 = 73 (0x49)

dstore_3 = 74 (0x4a)

Operand Stack

..., value

...

Description

Both <n> and <n>+1 must be indices into the local variable array of the current frame (2.6). The value on the top of the operand stack must be of type double. It is popped from the operand stack and undergoes value set conversion (2.8.3), resulting in value'. The local variables at <n> and <n>+1 are set to value'.

Notes

Each of the dstore_<n> instructions is the same as dstore with an index of <n>, except that the operand <n> is implicit.

dsub

Operation

Subtract double

Format

dsub

Forms

dsub = 103 (0x67)

Operand Stack

..., value1, value2

..., result

Description

Both value1 and value2 must be of type double. The values are popped from the operand stack and undergo value set conversion (2.8.3), resulting in value1' and value2'. The double result is value1' - value2'. The result is pushed onto the operand stack.

For double subtraction, it is always the case that a-b produces the same result as a+(-b). However, for the dsub instruction, subtraction from zero is not the same as negation, because if x is +0.0, then 0.0-x equals +0.0, but -x equals -0.0.

The Java Virtual Machine requires support of gradual underflow as defined by IEEE 754. (2.8). Despite the fact that overflow, underflow, or loss of precision may occur, execution of a dsub instruction never throws a run-time exception.

f2d

Operation

Convert float to double

Format

f2d

Forms

f2d = 141 (0x8d)

Operand Stack

..., value

..., result

Description

The value on the top of the operand stack must be of type float. It is popped from the operand stack and undergoes value set conversion (2.8.3), resulting in value'. Then value' is converted to a double result. This result is pushed onto the operand stack.

Notes

Where an f2d instruction is FP-strict (2.8.2) it performs a widening primitive conversion (JLS §5.1.2). Because all values of the float value set (2.3.2) are exactly representable by values of the double value set (2.3.2), such a conversion is exact.

Where an f2d instruction is not FP-strict, the result of the conversion may be taken from the double-extended-exponent value set; it is not necessarily rounded to the nearest representable value in the double value set. However, if the operand value is taken from the float-extended-exponent value set and the target result is constrained to the double value set, rounding of value may be required.

f2i

Operation

Convert float to int

Format

f2i

Forms

f2i = 139 (0x8b)

Operand Stack

..., value

..., result

Description

The value on the top of the operand stack must be of type float. It is popped from the operand stack and undergoes value set conversion (2.8.3), resulting in value'. Then value' is converted to an int result. This result is pushed onto the operand stack:

  • If the value' is NaN, the result of the conversion is an int 0.

  • Otherwise, if the value' is not an infinity, it is rounded to an integer value V, rounding towards zero V using IEEE 754 the round towards toward zero mode. rounding policy (2.8). If this integer value V can be represented as an int, then the result is the int value V.

  • Otherwise, either the value' must be too small (a negative value of large magnitude or negative infinity), and the result is the smallest representable value of type int, or the value' must be too large (a positive value of large magnitude or positive infinity), and the result is the largest representable value of type int.

Notes

The f2i instruction performs a narrowing primitive conversion (JLS §5.1.3). It may lose information about the overall magnitude of value' and may also lose precision.

f2l

Operation

Convert float to long

Format

f2l

Forms

f2l = 140 (0x8c)

Operand Stack

..., value

..., result

Description

The value on the top of the operand stack must be of type float. It is popped from the operand stack and undergoes value set conversion (2.8.3), resulting in value'. Then value' is converted to a long result. This result is pushed onto the operand stack:

  • If the value' is NaN, the result of the conversion is a long 0.

  • Otherwise, if the value' is not an infinity, it is rounded to an integer value V, rounding towards zero V using IEEE 754 the round towards toward zero mode. rounding policy (2.8). If this integer value V can be represented as a long, then the result is the long value V.

  • Otherwise, either the value' must be too small (a negative value of large magnitude or negative infinity), and the result is the smallest representable value of type long, or the value' must be too large (a positive value of large magnitude or positive infinity), and the result is the largest representable value of type long.

Notes

The f2l instruction performs a narrowing primitive conversion (JLS §5.1.3). It may lose information about the overall magnitude of value' and may also lose precision.

fadd

Operation

Add float

Format

fadd

Forms

fadd = 98 (0x62)

Operand Stack

..., value1, value2

..., result

Description

Both value1 and value2 must be of type float. The values are popped from the operand stack and undergo value set conversion (2.8.3), resulting in value1' and value2'. The float result is value1' + value2'. The result is pushed onto the operand stack.

The result of an fadd instruction is governed by the rules of IEEE 754 arithmetic:

  • If either value1' or value2' is NaN, the result is NaN.

  • The sum of two infinities of opposite sign is NaN.

  • The sum of two infinities of the same sign is the infinity of that sign.

  • The sum of an infinity and any finite value is equal to the infinity.

  • The sum of two zeroes of opposite sign is positive zero.

  • The sum of two zeroes of the same sign is the zero of that sign.

  • The sum of a zero and a nonzero finite value is equal to the nonzero value.

  • The sum of two nonzero finite values of the same magnitude and opposite sign is positive zero.

  • In the remaining cases, where neither operand is an infinity, a zero, or NaN and the values have the same sign or have different magnitudes, the sum is computed and rounded to the nearest representable value using IEEE 754 the round to nearest mode. rounding policy. If the magnitude is too large to represent as a float, we say the operation overflows; the result is then an infinity of appropriate sign. If the magnitude is too small to represent as a float, we say the operation underflows; the result is then a zero of appropriate sign.

The Java Virtual Machine requires support of gradual underflow as defined by IEEE 754. (2.8). Despite the fact that overflow, underflow, or loss of precision may occur, execution of an fadd instruction never throws a run-time exception.

faload

Operation

Load float from array

Format

faload

Forms

faload = 48 (0x30)

Operand Stack

..., arrayref, index

..., value

Description

The arrayref must be of type reference and must refer to an array whose components are of type float. The index must be of type int. Both arrayref and index are popped from the operand stack. The float value in the component of the array at index is retrieved and pushed onto the operand stack.

Run-time Exceptions

If arrayref is null, faload throws a NullPointerException.

Otherwise, if index is not within the bounds of the array referenced by arrayref, the faload instruction throws an ArrayIndexOutOfBoundsException.

fastore

Operation

Store into float array

Format

fastore

Forms

fastore = 81 (0x51)

Operand Stack

..., arrayref, index, value

...

Description

The arrayref must be of type reference and must refer to an array whose components are of type float. The index must be of type int, and the value must be of type float. The arrayref, index, and value are popped from the operand stack. The float value undergoes value set conversion (2.8.3), resulting in value', and value' is stored as the component of the array indexed by index.

Run-time Exceptions

If arrayref is null, fastore throws a NullPointerException.

Otherwise, if index is not within the bounds of the array referenced by arrayref, the fastore instruction throws an ArrayIndexOutOfBoundsException.

fcmp<op>

Operation

Compare float

Format

fcmp<op>

Forms

fcmpg = 150 (0x96)

fcmpl = 149 (0x95)

Operand Stack

..., value1, value2

..., result

Description

Both value1 and value2 must be of type float. The values are popped from the operand stack and undergo value set conversion (2.8.3), resulting in value1' and value2'. A floating-point comparison is performed:

  • If value1' is greater than value2', the int value 1 is pushed onto the operand stack.

  • Otherwise, if value1' is equal to value2', the int value 0 is pushed onto the operand stack.

  • Otherwise, if value1' is less than value2', the int value -1 is pushed onto the operand stack.

  • Otherwise, at least one of value1' or value2' is NaN. The fcmpg instruction pushes the int value 1 onto the operand stack and the fcmpl instruction pushes the int value -1 onto the operand stack.

Floating-point comparison is performed in accordance with IEEE 754. All values other than NaN are ordered, with negative infinity less than all finite values and positive infinity greater than all finite values. Positive zero and negative zero are considered equal.

Notes

The fcmpg and fcmpl instructions differ only in their treatment of a comparison involving NaN. NaN is unordered, so any float comparison fails if either or both of its operands are NaN. With both fcmpg and fcmpl available, any float comparison may be compiled to push the same result onto the operand stack whether the comparison fails on non-NaN values or fails because it encountered a NaN. For more information, see 3.5.

fconst_<f>

Operation

Push float

Format

fconst_<f>

Forms

fconst_0 = 11 (0xb)

fconst_1 = 12 (0xc)

fconst_2 = 13 (0xd)

Operand Stack

...

..., <f>

Description

Push the float constant <f> (0.0, 1.0, or 2.0) onto the operand stack.

fdiv

Operation

Divide float

Format

fdiv

Forms

fdiv = 110 (0x6e)

Operand Stack

..., value1, value2

..., result

Description

Both value1 and value2 must be of type float. The values are popped from the operand stack and undergo value set conversion (2.8.3), resulting in value1' and value2'. The float result is value1' / value2'. The result is pushed onto the operand stack.

The result of an fdiv instruction is governed by the rules of IEEE 754 arithmetic:

  • If either value1' or value2' is NaN, the result is NaN.

  • If neither value1' nor value2' is NaN, the sign of the result is positive if both values have the same sign, negative if the values have different signs.

  • Division of an infinity by an infinity results in NaN.

  • Division of an infinity by a finite value results in a signed infinity, with the sign-producing rule just given.

  • Division of a finite value by an infinity results in a signed zero, with the sign-producing rule just given.

  • Division of a zero by a zero results in NaN; division of zero by any other finite value results in a signed zero, with the sign-producing rule just given.

  • Division of a nonzero finite value by a zero results in a signed infinity, with the sign-producing rule just given.

  • In the remaining cases, where neither operand is an infinity, a zero, or NaN, the quotient is computed and rounded to the nearest float using IEEE 754 the round to nearest mode. rounding policy. If the magnitude is too large to represent as a float, we say the operation overflows; the result is then an infinity of appropriate sign. If the magnitude is too small to represent as a float, we say the operation underflows; the result is then a zero of appropriate sign.

The Java Virtual Machine requires support of gradual underflow as defined by IEEE 754. (2.8). Despite the fact that overflow, underflow, division by zero, or loss of precision may occur, execution of an fdiv instruction never throws a run-time exception.

fload

Operation

Load float from local variable

Format

fload
index

Forms

fload = 23 (0x17)

Operand Stack

...

..., value

Description

The index is an unsigned byte that must be an index into the local variable array of the current frame (2.6). The local variable at index must contain a float. The value of the local variable at index is pushed onto the operand stack.

Notes

The fload opcode can be used in conjunction with the wide instruction (6.5.wide) to access a local variable using a two-byte unsigned index.

fload_<n>

Operation

Load float from local variable

Format

fload_<n>

Forms

fload_0 = 34 (0x22)

fload_1 = 35 (0x23)

fload_2 = 36 (0x24)

fload_3 = 37 (0x25)

Operand Stack

...

..., value

Description

The <n> must be an index into the local variable array of the current frame (2.6). The local variable at <n> must contain a float. The value of the local variable at <n> is pushed onto the operand stack.

Notes

Each of the fload_<n> instructions is the same as fload with an index of <n>, except that the operand <n> is implicit.

fmul

Operation

Multiply float

Format

fmul

Forms

fmul = 106 (0x6a)

Operand Stack

..., value1, value2

..., result

Description

Both value1 and value2 must be of type float. The values are popped from the operand stack and undergo value set conversion (2.8.3), resulting in value1' and value2'. The float result is value1' * value2'. The result is pushed onto the operand stack.

The result of an fmul instruction is governed by the rules of IEEE 754 arithmetic:

  • If either value1' or value2' is NaN, the result is NaN.

  • If neither value1' nor value2' is NaN, the sign of the result is positive if both values have the same sign, and negative if the values have different signs.

  • Multiplication of an infinity by a zero results in NaN.

  • Multiplication of an infinity by a finite value results in a signed infinity, with the sign-producing rule just given.

  • In the remaining cases, where neither an infinity nor NaN is involved, the product is computed and rounded to the nearest representable value using IEEE 754 the round to nearest mode. rounding policy. If the magnitude is too large to represent as a float, we say the operation overflows; the result is then an infinity of appropriate sign. If the magnitude is too small to represent as a float, we say the operation underflows; the result is then a zero of appropriate sign.

The Java Virtual Machine requires support of gradual underflow as defined by IEEE 754. (2.8). Despite the fact that overflow, underflow, or loss of precision may occur, execution of an fmul instruction never throws a run-time exception.

fneg

Operation

Negate float

Format

fneg

Forms

fneg = 118 (0x76)

Operand Stack

..., value

..., result

Description

The value must be of type float. It is popped from the operand stack and undergoes value set conversion (2.8.3), resulting in value'. The float result is the arithmetic negation of value'. This result is pushed onto the operand stack.

For float values, negation is not the same as subtraction from zero. If x is +0.0, then 0.0-x equals +0.0, but -x equals -0.0. Unary minus merely inverts the sign of a float.

Special cases of interest:

  • If the operand is NaN, the result is NaN (recall that NaN has no sign).

  • If the operand is an infinity, the result is the infinity of opposite sign.

  • If the operand is a zero, the result is the zero of opposite sign.

frem

Operation

Remainder float

Format

frem

Forms

frem = 114 (0x72)

Operand Stack

..., value1, value2

..., result

Description

Both value1 and value2 must be of type float. The values are popped from the operand stack and undergo value set conversion (2.8.3), resulting in value1' and value2'. The result is calculated and pushed onto the operand stack as a float.

The result of a frem instruction is not the same as that of the so-calledthe remainder operation defined by IEEE 754 due to the choice of rounding policy (2.8). The IEEE 754 "remainder" operation computes the remainder from a an implied division using the round to nearest rounding policy ("rounding division"), not an implied division using the round toward zero rounding policy ("truncating division"), and so its behavior is not analogous to that of the usual integer remainder operator. Instead, the Java Virtual Machine defines frem to behave in a manner analogous to that of the Java Virtual Machine integer remainder instructions (irem and lrem); this may be compared with the C library function fmod.

The result of a frem instruction is governed by these rules, which match the rules for IEEE 754 remainder other than how the implied division is computed:

  • If either value1' or value2' is NaN, the result is NaN.

  • If neither value1' nor value2' is NaN, the sign of the result equals the sign of the dividend.

  • If the dividend is an infinity or the divisor is a zero or both, the result is NaN.

  • If the dividend is finite and the divisor is an infinity, the result equals the dividend.

  • If the dividend is a zero and the divisor is finite, the result equals the dividend.

  • In the remaining cases, where neither operand is an infinity, a zero, or NaN, the floating-point remainder result from a dividend value1' and a divisor value2' is defined by the mathematical relation result = value1' - (value2' * q), where q is an integer that is negative only if value1' / value2' is negative and positive only if value1' / value2' is positive, and whose magnitude is as large as possible without exceeding the magnitude of the true mathematical quotient of value1' and value2'.

Despite the fact that division by zero may occur, evaluation of an frem instruction never throws a run-time exception. Overflow, underflow, or loss of precision cannot occur.

Notes

The IEEE 754 remainder operation may be computed by the library routine Math.IEEEremainder or StrictMath.IEEEremainder.

freturn

Operation

Return float from method

Format

freturn

Forms

freturn = 174 (0xae)

Operand Stack

..., value

[empty]

Description

The current method must have return type float. The value must be of type float. If the current method is a synchronized method, the monitor entered or reentered on invocation of the method is updated and possibly exited as if by execution of a monitorexit instruction (6.5.monitorexit) in the current thread. If no exception is thrown, value is popped from the operand stack of the current frame (2.6) and undergoes value set conversion (2.8.3), resulting in value'. The value' is pushed onto the operand stack of the frame of the invoker. Any other values on the operand stack of the current method are discarded.

The interpreter then returns control to the invoker of the method, reinstating the frame of the invoker.

Run-time Exceptions

If the Java Virtual Machine implementation does not enforce the rules on structured locking described in 2.11.10, then if the current method is a synchronized method and the current thread is not the owner of the monitor entered or reentered on invocation of the method, freturn throws an IllegalMonitorStateException. This can happen, for example, if a synchronized method contains a monitorexit instruction, but no monitorenter instruction, on the object on which the method is synchronized.

Otherwise, if the Java Virtual Machine implementation enforces the rules on structured locking described in 2.11.10 and if the first of those rules is violated during invocation of the current method, then freturn throws an IllegalMonitorStateException.

fstore

Operation

Store float into local variable

Format

fstore
index

Forms

fstore = 56 (0x38)

Operand Stack

..., value

...

Description

The index is an unsigned byte that must be an index into the local variable array of the current frame (2.6). The value on the top of the operand stack must be of type float. It is popped from the operand stack and undergoes value set conversion (2.8.3), resulting in value'. The value of the local variable at index is set to value'.

Notes

The fstore opcode can be used in conjunction with the wide instruction (6.5.wide) to access a local variable using a two-byte unsigned index.

fstore_<n>

Operation

Store float into local variable

Format

fstore_<n>

Forms

fstore_0 = 67 (0x43)

fstore_1 = 68 (0x44)

fstore_2 = 69 (0x45)

fstore_3 = 70 (0x46)

Operand Stack

..., value

...

Description

The <n> must be an index into the local variable array of the current frame (2.6). The value on the top of the operand stack must be of type float. It is popped from the operand stack and undergoes value set conversion (2.8.3), resulting in value'. The value of the local variable at <n> is set to value'.

Notes

Each of the fstore_<n> instructions is the same as fstore with an index of <n>, except that the operand <n> is implicit.

fsub

Operation

Subtract float

Format

fsub

Forms

fsub = 102 (0x66)

Operand Stack

..., value1, value2

..., result

Description

Both value1 and value2 must be of type float. The values are popped from the operand stack and undergo value set conversion (2.8.3), resulting in value1' and value2'. The float result is value1' - value2'. The result is pushed onto the operand stack.

For float subtraction, it is always the case that a-b produces the same result as a+(-b). However, for the fsub instruction, subtraction from zero is not the same as negation, because if x is +0.0, then 0.0-x equals +0.0, but -x equals -0.0.

The Java Virtual Machine requires support of gradual underflow as defined by IEEE 754. (2.8). Despite the fact that overflow, underflow, or loss of precision may occur, execution of an fsub instruction never throws a run-time exception.

i2d

Operation

Convert int to double

Format

i2d

Forms

i2d = 135 (0x87)

Operand Stack

..., value

..., result

Description

The value on the top of the operand stack must be of type int. It is popped from the operand stack and converted to a double result. The result is pushed onto the operand stack.

Notes

The i2d instruction performs a widening primitive conversion (JLS §5.1.2). Because all values of type int are exactly representable by type double, the conversion is exact.

i2f

Operation

Convert int to float

Format

i2f

Forms

i2f = 134 (0x86)

Operand Stack

..., value

..., result

Description

The value on the top of the operand stack must be of type int. It is popped from the operand stack and converted to the float result using IEEE 754 the round to nearest mode. rounding policy. The result is pushed onto the operand stack.

Notes

The i2f instruction performs a widening primitive conversion (JLS §5.1.2), but may result in a loss of precision because values of type float have only 24 significand bits.

l2d

Operation

Convert long to double

Format

l2d

Forms

l2d = 138 (0x8a)

Operand Stack

..., value

..., result

Description

The value on the top of the operand stack must be of type long. It is popped from the operand stack and converted to a double result using IEEE 754 the round to nearest mode. rounding policy. The result is pushed onto the operand stack.

Notes

The l2d instruction performs a widening primitive conversion (JLS §5.1.2) that may lose precision because values of type double have only 53 significand bits.

l2f

Operation

Convert long to float

Format

l2f

Forms

l2f = 137 (0x89)

Operand Stack

..., value

..., result

Description

The value on the top of the operand stack must be of type long. It is popped from the operand stack and converted to a float result using IEEE 754 the round to nearest mode. rounding policy. The result is pushed onto the operand stack.

Notes

The l2f instruction performs a widening primitive conversion (JLS §5.1.2) that may lose precision because values of type float have only 24 significand bits.

ldc

Operation

Push item from run-time constant pool

Format

ldc
index

Forms

ldc = 18 (0x12)

Operand Stack

...

..., value

Description

The index is an unsigned byte that must be a valid index into the run-time constant pool of the current class (2.5.5). The run-time constant pool entry at index must be loadable (5.1), and not any of the following:

  • A numeric constant of type long or double.

  • A symbolic reference to a dynamically-computed constant whose field descriptor is J (denoting long) or D (denoting double).

If the run-time constant pool entry is a numeric constant of type int or float, then the value of that numeric constant is pushed onto the operand stack as an int or float, respectively.

Otherwise, if the run-time constant pool entry is a string constant, that is, a reference to an instance of class String, then value, a reference to that instance, is pushed onto the operand stack.

Otherwise, if the run-time constant pool entry is a symbolic reference to a class or interface, then the named class or interface is resolved (5.4.3.1) and value, a reference to the Class object representing that class or interface, is pushed onto the operand stack.

Otherwise, the run-time constant pool entry is a symbolic reference to a method type, a method handle, or a dynamically-computed constant. The symbolic reference is resolved (5.4.3.5, 5.4.3.6) and value, the result of resolution, is pushed onto the operand stack.

Linking Exceptions

During resolution of a symbolic reference, any of the exceptions pertaining to resolution of that kind of symbolic reference can be thrown.

Notes

The ldc instruction can only be used to push a value of type float taken from the float value set (2.3.2) because a constant of type float in the constant pool (4.4.4) must be taken from the float value set.

ldc_w

Operation

Push item from run-time constant pool (wide index)

Format

ldc_w
indexbyte1
indexbyte2

Forms

ldc_w = 19 (0x13)

Operand Stack

...

..., value

Description

The unsigned indexbyte1 and indexbyte2 are assembled into an unsigned 16-bit index into the run-time constant pool of the current class (2.5.5), where the value of the index is calculated as (indexbyte1 << 8) | indexbyte2. The index must be a valid index into the run-time constant pool of the current class. The run-time constant pool entry at the index must be loadable (5.1), and not any of the following:

  • A numeric constant of type long or double.

  • A symbolic reference to a dynamically-computed constant whose field descriptor is J (denoting long) or D (denoting double).

If the run-time constant pool entry is a numeric constant of type int or float, or a string constant, then value is determined and pushed onto the operand stack according to the rules given for the ldc instruction.

Otherwise, the run-time constant pool entry is a symbolic reference to a class, interface, method type, method handle, or dynamically-computed constant. It is resolved and value is determined and pushed onto the operand stack according to the rules given for the ldc instruction.

Linking Exceptions

During resolution of a symbolic reference, any of the exceptions pertaining to resolution of that kind of symbolic reference can be thrown.

Notes

The ldc_w instruction is identical to the ldc instruction (6.5.ldc) except for its wider run-time constant pool index.

The ldc_w instruction can only be used to push a value of type float taken from the float value set (2.3.2) because a constant of type float in the constant pool (4.4.4) must be taken from the float value set.

ldc2_w

Operation

Push long or double from run-time constant pool (wide index)

Format

ldc2_w
indexbyte1
indexbyte2

Forms

ldc2_w = 20 (0x14)

Operand Stack

...

..., value

Description

The unsigned indexbyte1 and indexbyte2 are assembled into an unsigned 16-bit index into the run-time constant pool of the current class (2.5.5), where the value of the index is calculated as (indexbyte1 << 8) | indexbyte2. The index must be a valid index into the run-time constant pool of the current class. The run-time constant pool entry at the index must be loadable (5.1), and in particular one of the following:

  • A numeric constant of type long or double.

  • A symbolic reference to a dynamically-computed constant whose field descriptor is J (denoting long) or D (denoting double).

If the run-time constant pool entry is a numeric constant of type long or double, then the value of that numeric constant is pushed onto the operand stack as a long or double, respectively.

Otherwise, the run-time constant pool entry is a symbolic reference to a dynamically-computed constant. The symbolic reference is resolved (5.4.3.6) and value, the result of resolution, is pushed onto the operand stack.

Linking Exceptions

During resolution of a symbolic reference to a dynamically-computed constant, any of the exceptions pertaining to dynamically-computed constant resolution can be thrown.

Notes

Only a wide-index version of the ldc2_w instruction exists; there is no ldc2 instruction that pushes a long or double with a single-byte index.

The ldc2_w instruction can only be used to push a value of type double taken from the double value set (2.3.2) because a constant of type double in the constant pool (4.4.5) must be taken from the double value set.

Appendix A: Limited License Grant

ORACLE AMERICA, INC. IS WILLING TO LICENSE THIS SPECIFICATION TO YOU ONLY UPON THE CONDITION THAT YOU ACCEPT ALL OF THE TERMS CONTAINED IN THIS AGREEMENT ("AGREEMENT"). PLEASE READ THE TERMS AND CONDITIONS OF THIS AGREEMENT CAREFULLY.

Specification: JSR-389 Java SE 14
Version: 14
Status: Final Release
Release: March 2020

Copyright © 1997, 2020, Oracle America, Inc.
All rights reserved.

LIMITED LICENSE GRANTS

  1. License for Evaluation Purposes. Specification Lead hereby grants you a fully-paid, non-exclusive, non-transferable, worldwide, limited license (without the right to sublicense), under Specification Lead's applicable intellectual property rights to view, download, use and reproduce the Specification only for the purpose of internal evaluation. This includes (i) developing applications intended to run on an implementation of the Specification, provided that such applications do not themselves implement any portion(s) of the Specification, and (ii) discussing the Specification with any third party; and (iii) excerpting brief portions of the Specification in oral or written communications which discuss the Specification provided that such excerpts do not in the aggregate constitute a significant portion of the Specification.

  2. License for the Distribution of Compliant Implementations. Specification Lead also grants you a perpetual, non-exclusive, non-transferable, worldwide, fully paid-up, royalty free, limited license (without the right to sublicense) under any applicable copyrights or, subject to the provisions of subsection 4 below, patent rights it may have covering the Specification to create and/or distribute an Independent Implementation of the Specification that: (a) fully implements the Specification including all its required interfaces and functionality; (b) does not modify, subset, superset or otherwise extend the Licensor Name Space, or include any public or protected packages, classes, Java interfaces, fields or methods within the Licensor Name Space other than those required/authorized by the Specification or Specifications being implemented; and (c) passes the Technology Compatibility Kit (including satisfying the requirements of the applicable TCK Users Guide) for such Specification ("Compliant Implementation"). In addition, the foregoing license is expressly conditioned on your not acting outside its scope. No license is granted hereunder for any other purpose (including, for example, modifying the Specification, other than to the extent of your fair use rights, or distributing the Specification to third parties). Also, no right, title, or interest in or to any trademarks, service marks, or trade names of Specification Lead or Specification Lead's licensors is granted hereunder. Java, and Java-related logos, marks and names are trademarks or registered trademarks of Oracle America, Inc. in the U.S. and other countries.

  3. Pass-through Conditions. You need not include limitations (a)-(c) from the previous paragraph or any other particular "pass through" requirements in any license You grant concerning the use of your Independent Implementation or products derived from it. However, except with respect to Independent Implementations (and products derived from them) that satisfy limitations (a)-(c) from the previous paragraph, You may neither: (a) grant or otherwise pass through to your licensees any licenses under Specification Lead's applicable intellectual property rights; nor
  1. authorize your licensees to make any claims concerning their implementation's compliance with the Specification in question.
  1. Reciprocity Concerning Patent Licenses.
  1. With respect to any patent claims covered by the license granted under subparagraph 2 above that would be infringed by all technically feasible implementations of the Specification, such license is conditioned upon your offering on fair, reasonable and non-discriminatory terms, to any party seeking it from You, a perpetual, non-exclusive, non-transferable, worldwide license under Your patent rights which are or would be infringed by all technically feasible implementations of the Specification to develop, distribute and use a Compliant Implementation.

  2. With respect to any patent claims owned by Specification Lead and covered by the license granted under subparagraph 2, whether or not their infringement can be avoided in a technically feasible manner when implementing the Specification, such license shall terminate with respect to such claims if You initiate a claim against Specification Lead that it has, in the course of performing its responsibilities as the Specification Lead, induced any other entity to infringe Your patent rights.

  3. Also with respect to any patent claims owned by Specification Lead and covered by the license granted under subparagraph 2 above, where the infringement of such claims can be avoided in a technically feasible manner when implementing the Specification such license, with respect to such claims, shall terminate if You initiate a claim against Specification Lead that its making, having made, using, offering to sell, selling or importing a Compliant Implementation infringes Your patent rights.

  1. Definitions. For the purposes of this Agreement: "Independent Implementation" shall mean an implementation of the Specification that neither derives from any of Specification Lead's source code or binary code materials nor, except with an appropriate and separate license from Specification Lead, includes any of Specification Lead's source code or binary code materials; "Licensor Name Space" shall mean the public class or interface declarations whose names begin with "java", "javax", "com.oracle", "com.sun" or their equivalents in any subsequent naming convention adopted by Oracle America, Inc. through the Java Community Process, or any recognized successors or replacements thereof; and "Technology Compatibility Kit" or "TCK" shall mean the test suite and accompanying TCK User's Guide provided by Specification Lead which corresponds to the Specification and that was available either (i) from Specification Lead 120 days before the first release of Your Independent Implementation that allows its use for commercial purposes, or (ii) more recently than 120 days from such release but against which You elect to test Your implementation of the Specification.

This Agreement will terminate immediately without notice from Specification Lead if you breach the Agreement or act outside the scope of the licenses granted above.

DISCLAIMER OF WARRANTIES

THE SPECIFICATION IS PROVIDED "AS IS". SPECIFICATION LEAD MAKES NO REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT (INCLUDING AS A CONSEQUENCE OF ANY PRACTICE OR IMPLEMENTATION OF THE SPECIFICATION), OR THAT THE CONTENTS OF THE SPECIFICATION ARE SUITABLE FOR ANY PURPOSE. This document does not represent any commitment to release or implement any portion of the Specification in any product. In addition, the Specification could include technical inaccuracies or typographical errors.

LIMITATION OF LIABILITY

TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT WILL SPECIFICATION LEAD OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES, INCLUDING WITHOUT LIMITATION, LOST REVENUE, PROFITS OR DATA, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF OR RELATED IN ANY WAY TO YOUR HAVING, IMPLEMENTING OR OTHERWISE USING THE SPECIFICATION, EVEN IF SPECIFICATION LEAD AND/OR ITS LICENSORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

You will indemnify, hold harmless, and defend Specification Lead and its licensors from any claims arising or resulting from: (i) your use of the Specification; (ii) the use or distribution of your Java application, applet and/or implementation; and/or (iii) any claims that later versions or releases of any Specification furnished to you are incompatible with the Specification provided to you under this license.

RESTRICTED RIGHTS LEGEND

U.S. Government: If this Specification is being acquired by or on behalf of the U.S. Government or by a U.S. Government prime contractor or subcontractor (at any tier), then the Government's rights in the Software and accompanying documentation shall be only as set forth in this license; this is in accordance with 48 C.F.R. 227.7201 through 227.7202-4 (for Department of Defense (DoD) acquisitions) and with 48 C.F.R. 2.101 and 12.212 (for non-DoD acquisitions).

REPORT

If you provide Specification Lead with any comments or suggestions concerning the Specification ("Feedback"), you hereby: (i) agree that such Feedback is provided on a non-proprietary and non-confidential basis, and (ii) grant Specification Lead a perpetual, non-exclusive, worldwide, fully paid-up, irrevocable license, with the right to sublicense through multiple levels of sublicensees, to incorporate, disclose, and use without limitation the Feedback for any purpose.

GENERAL TERMS

Any action related to this Agreement will be governed by California law and controlling U.S. federal law. The U.N. Convention for the International Sale of Goods and the choice of law rules of any jurisdiction will not apply.

The Specification is subject to U.S. export control laws and may be subject to export or import regulations in other countries. Licensee agrees to comply strictly with all such laws and regulations and acknowledges that it has the responsibility to obtain such licenses to export, re-export or import as may be required after delivery to Licensee.

This Agreement is the parties' entire agreement relating to its subject matter. It supersedes all prior or contemporaneous oral or written communications, proposals, conditions, representations and warranties and prevails over any conflicting or additional terms of any quote, order, acknowledgment, or other communication between the parties relating to its subject matter during the term of this Agreement. No modification to this Agreement will be binding, unless in writing and signed by an authorized representative of each party.