scScript Numbers
scScript relies heavily on C (and its runtime library, libc) for
its numerical computations and math support. Numbers can be represented
in integer (Int) or floating point (Flt) format.
The former is really just 64bit signed integers (Int64
in sources) while the latter is standard C double float
(double in C). In addition to C arithmetic operators,
scScript also provides a Math package with support for
logarithms, exponentiation, square roots, and basic trigonometry.
Integers can be written in signed decimal, hexadecimal (hex), and octal format:
X = -42; X = -0x2a; X = -052;
All three assign -42 (decimal) to X. Note
the leading 0x for hex and leading 0 for
octal. Importantly, scScript does not sign extend, so 0xFF
is just 255, not -1!
Floating point numbers can only be written in signed decimal or hex:
X = -42.1875; X = -0x2a.3;
Both will assign -42.1875 to X. In the case
of hex, 2a is decimal 42 and .3
brings 3/16 as each digit is a power of 16 on
the denominator. Similarly, .35 in hex would
mean 3/16 + 5/256 == 0.20703125. But, -052.3
will be promoted to decimal (not octal) and read as
simply -52.3, despite the leading 0.
Floating point numbers, both decimal and hex, can also be written in exponential format:
X = 8.64E4; X = -0x2a.3P11;
Both will assign 86400.0 to X. In the
decimal case the number is 8.64 * 104 while the
hex number is really 42.1875 * 211. Whereas the
E (or e) for Exponent is readily obvious, the
hex format must do with P (or p)
for Power as E is a valid hex digit! Also, the base
of an exponential number can be in decimal or hex, but the exponent is
only written in decimal. So the 11
in -0x2a.3P11 really means 211 and not
20x11 which would be 64 times bigger.
When two large integers are added (or multiplied), it is entirely
possible to overflow the 64 bits and create numerically erroneous results
as bits roll over with no obvious warning. But this is not the case with
floating point numbers. These reserve special values to flag
overflow/underflow conditions as Inf and -Inf.
Subsequent numerical operations will preserve these values and their
specific semantics. For example: Inf/2 and (Inf -
1000.0) still yield Inf. A NaN
(Not-a-Number) value is also reserved and created for specific
situations, as in (0.0/0.0). NaN has the
surprising attribute of not being equal to itself, as it
is outside the closed realm of numbers! (But, NaN is
identical (===) to itself!)
Print and Write functions in scScript will use libc for
displaying numbers. These will therefore display inf
and -inf where appropriate. Strangely
though, libc currently displays NaN with a
negative sign, apparently because the floating point value reserved for
NaN is negative. These special values are typically
generated as part of degenerate floating computations, but on the off
chance that one actually needs such values, the Math
package defines #Nan, #Pos_Inf
and #Neg_Inf constants.
Note:
NaN and Inf are theoretical concepts.
"-nan", "inf", and "-inf" are
what scScript prints, thanks to Libc.
#Nan, #Pos_Inf, and
#Neg_Inf are Defs in the Math
package that can be used in scripts.
scScript will optimize simple arithmetic at compile time. So the
statement:
Math.Sin((45 * Math.#Pi) / 180)
becomes
X = Math.Sin(0.785398)
As of this writing, the compiler does not pre-compute the Sin function itself!