Extended mode adds the Long signed 64-bit integer type and the
Double IEEE 754 binary64 floating-point type. They are real language and
ABI types: values remain 64 bits in expressions, calls, returns, variables,
Fields, arrays, collections, Data, Banks, streams, the debugger, and
UserLib calls. Compile with --mode extended or select Extended in
Program Options. Original mode neither reserves these names nor accepts their
literals or annotations.
| Type | Annotation | Default | Literal forms |
|---|---|---|---|
| Long | :Long | 0L | 5000000000L, $1122334455667788L, %1010L |
| Double | :Double | 0.0D | 1.5D, 1D, 6.022e23D, .25D |
Long ranges from -9223372036854775808L through
9223372036854775807L. Double has 53 bits of significand precision,
about 15 to 17 significant decimal digits. A suffix is required to make a wide
literal; an unsuffixed whole number remains Int and an unsuffixed decimal
remains Float.
Dialect "modern"
Global ticks:Long = 5000000000L
Local precise:Double = 9007199254740991.0D
Dim samples:Double(63)
Type Measurement
Field sequence:Long = 1L
Field value:Double = 0.0D
End Type
:Long and :Double use named annotations and
therefore require Dialect "modern". They are valid for Globals,
Locals, Constants, parameters, Function and Method returns, Fields, dynamic
arrays, Extended fixed arrays, and collection element/key/value types.
For numeric arithmetic and comparison, Double dominates every numeric type. Long combined with Float also produces Double so a Long is never silently narrowed to Float. Otherwise Long dominates Int. Comparisons still return Int True or False.
| Conversion | Behavior |
|---|---|
| Int to Long; Float to Double | Exact. |
| Long to Double | Rounded to the nearest representable binary64 value, ties to even. |
| Int or Long to Float | Rounded to binary32 precision. |
| Float or Double to Long | Truncated toward zero; NaN, infinity, and out-of-range values raise a runtime error. |
| Float or Double to Int | Uses the characterized legacy Int conversion behavior. |
| String to Long/Double | The whole String must be a valid number; trailing non-numeric text raises a runtime error. |
| Any numeric type to String | Produces a round-trip decimal representation; Double preserves negative zero. |
The explicit conversions are Long(value) and
Double(value). The existing Int, Float,
and Str conversions accept the new types.
Long addition, subtraction, multiplication, negation, and left shift use
two's-complement modulo-264 results. And, Or,
Xor, and ~ operate on all 64 bits. Shift counts are
masked to 0 through 63, including negative counts. Shr is logical
and Sar preserves the sign bit. Division truncates toward zero;
division or Mod by zero raises a runtime error. The otherwise
unrepresentable LongMin / -1L result wraps to LongMin and its
remainder is zero.
Double expression results are binary64 values rounded to nearest, ties to
even. Generated code does not retain wider x87 intermediates. All arithmetic
NaNs are canonicalized to quiet NaN bits $7ff8000000000000L;
comparisons with NaN follow IEEE rules, so every ordered comparison and equality
is False and inequality is True. Signed zero is preserved. Double division by
positive or negative zero follows IEEE 754, producing a signed infinity for a
nonzero numerator and the canonical NaN for zero divided by zero.
The following deterministic Double commands use degrees for angles and a pinned fdlibm implementation shared by constant folding and runtime execution:
SinD CosD TanD ASinD ACosD ATanD ATan2D SqrtD ExpD LogD Log10D PowD ModD FloorD CeilD TruncD RoundD
Extended mode also provides raw-radian variants for algorithms whose angle values are already expressed in radians:
SinRadD CosRadD TanRadD ASinRadD ACosRadD ATanRadD ATan2RadD
The forward functions consume radians and the inverse functions return
radians. ATan2RadD(y,x) keeps the same parameter order as
ATan2D. These commands call the pinned fdlibm implementation
directly, preserve signed zero, follow its infinity and quadrant behavior, and
canonicalize every NaN result to $7ff8000000000000L. They do not
perform a degree/radian conversion and do not change any existing degree-based
command.
RoundD rounds to the nearest integral Double with ties to even.
Domain errors return the canonical NaN; overflow produces infinity where IEEE
754 specifies it. These commands and Double arithmetic have matching raw result
bits in supported 32-bit and 64-bit builds. A native UserLib must preserve the
floating-point environment across a call.
| Command | Result |
|---|---|
FloatBits(float) | Returns the unchanged 32-bit representation as Int. |
FloatFromBits(int) | Creates a Float from unchanged bits. |
DoubleBits(double) | Returns the unchanged 64-bit representation as Long. |
DoubleFromBits(long) | Creates a Double from unchanged bits. |
Bit casts do not perform a numeric conversion and preserve every bit, including NaN payloads and signed zero. A later arithmetic operation may apply the canonical-NaN rule.
Long and Double retain their type in scalar variables, Fields, dynamic and fixed arrays, multidimensional arrays, List/Map/Set/Queue/Stack values, calls, returns, and mixed Data tables. Read converts the next item to the type of its destination; Restore works as usual.
Data 5000000000L, 0.1D Read id:Long, fraction:Double
Banks use PeekLong/PokeLong and
PeekDouble/PokeDouble. Streams use
ReadLong/WriteLong and
ReadDouble/WriteDouble. Each reads or writes exactly
eight bytes in the same little-endian format used by existing Int and Float
commands. Unaligned Bank offsets are supported; debug builds bounds-check all
eight bytes.
Double Map and Set keys compare numerically. Positive and negative zero are the same key. NaN is rejected as a key because it cannot form a stable equality relation.
Function Accumulate:Long(total:Long, amount:Long)
Return total + amount
End Function
Function Hypotenuse:Double(x:Double, y:Double)
Return SqrtD(x*x + y*y)
End Function
Wide values use the same declaration, default-argument, recursion, Method, and Interface rules as other basic values. The compiler preserves the complete 64-bit value through the 32-bit and 64-bit internal ABIs. The debugger displays Long as signed decimal and Double with enough digits to reconstruct the same bits.
UserLib declarations use readable annotations such as
EchoLong:Long(value:Long) and
EchoDouble:Double(value:Double). See the bundled
userlibs/UserLibs.txt for the exact native ABI rules.
See samples/language/11_Long_And_Double.bb for a runnable
self-checking program that combines declarations, arrays, Fields, Functions,
bit casts, storage, and deterministic math.