# integer

Definition: | integer identifier -- or -- bool res = integer(object x) -- or -- int identifier -- or -- bool res = int(object x)
Description: | This serves to define the integer type. int is just a simple alias of integer. You can also call it like an ordinary function to determine whether an object is an integer.
pwa/p2js: | Supported, however JavaScript is a typeless language, with "`integer i`" being mapped to "`let /*integer*/ i;`" and there are no run-time typechecks, or at least they are very rare (see implementation notes below). An explicit hll/Phix "if integer(x)" and similar expressions all work under pwa/p2js exactly as expected, except for: Note that within JavaScript, an integer is +/-9,007,199,254,740,992 (ie 2^53). [you may need explicit checks, as next] Also note this function yields true for booleans and routine_ids, whereas JavaScript’s Number.isInteger() does not.
Comments: | When invoked as a function, returns true (1) if x is an integer, otherwise false (0). On 32-bit, integers are whole numbers in the range -1,073,741,824 to +1,073,741,823 On 64-bit, integers are whole numbers in the range -4,611,686,018,427,387,904 to +4,611,686,018,427,387,903 In hex those limits are -#40000000[00000000] to +#3FFFFFFF[FFFFFFFF], technically 31/63-bit respectively. Obviously, however, any code which should work identically on both 32 and 64-bit should [explicitly] respect the 32-bit limits.
Supplemental: | In psym.e (part of the compiler), bool is a simple alias of integer, which does not validate that the value is true(1) or false(0) only - instead, 0 is false, and any other value is deemed true. However there is a more rigorous version, boolean, defined in builtins/ptypes.e - not an autoinclude but used/included by pGUI, mpfr, cffi, and hence indirectly builtins\structs.e, so any of those will make it available. Obviously there is no harm whatsoever in storing a boolean in a bool or integer, and only rarely is there any advantage to using the former. Ideally boolean variables should (probably) begin with is/are/has or similar, eg isVisible/areEqual/hasEncryption in preference to visible/equal/encryption, or perhaps say bUgly (aka hungarian notation), with identifiers such as is_visible being more suggestive of a function that presumably returns a true/false result. Admittedly I tend to mix and mash those sort of rules and rather than getting too pedantic, try to focus on communicating the underlying intent as clearly as reasonably possible. The builtin constants true and false can and should be used for variables and parameters declared as type bool[ean], or, if you prefer, TRUE, True, FALSE, and False, are identical/aliases - mainly for compatibility with legacy code, but ultimately also one less thing (upper/lower case) that you have to remember, or fix.
Example 1: |
    integer z = -1
Example 2: |
    if integer(y/x) then
        puts(1, "y is an exact multiple of x")
    end if
Implementation: | There are generic versions of the integer function implemented as :%opInt in builtins\VM\pType.e and :%opInt0 in builtins\VM\pJcc.e that the compiler only invokes as a last resort, preferring instead to inline that functionality if the argument is known to be assigned or the result variable, if any, is known to be an integer, ie does not require decref/dealloc. The compiler may also completely omit the test and/or any related code, if type inference/propagation determines that the result will always be true or always false. As already mentioned, builtins/ptypes.e is where the supplemental types are defined. The file pwa/p2js.js defines integer() with an optional name parameter, which if not "" triggers unassigned or type check errors, but that (parameter) is not intended for or available from hll/Phix code, and only meant for use in manually hand-crafted replacements elsewhere in p2js.js, and in practice it ended up being invoked (that way) rather more sparingly than first predicted.
See Also: | atom, sequence, string, object, floor, puts, Core Language
Technicalia | A value such as '123456.0000000001' could appear as '123456' in trace, ex.err, and other diagnostic output, because the standard default is to display a maximum of six decimal places. A trailing ".0" is now added by print() and sprint() [see builtins\VM\psprintN.e] when a non-integer atom value is rounded in such a manner by sprintf(), to avoid that potential source of confusion. (To reiterate what I just said: sprintf() may chop off a trailing ".0"; sprint() [without the f] may stick it back on.) Phix does not have an unsigned integer type - since the downsides of unexpected and ludicrous math results far outweigh any possible benefits, and besides, the 31/63 bit aspect would slap a massive black hole smack in the middle of an extended unsigned range anyway, as in #00..#3F ok, #40..BF fail, #C0..#FF ok, making them completely useless, but atoms can cope perfectly well enough. The most significant loss here would be that a C-style `(unsigned)idx < s.len` must be replaced with `idx>=1 and idx<=length(s)`, plus a couple of abs() calls if you also want to allow negative subscripts. The sq_int() routine can be used to apply an integer() test to all top-level elements of a sequence, eg `sq_int({1,1.5,"string",{1,1.5,"string",{}}) ==> {true,false,false,false}`. That routine returns a single true/false if passed an atom or string, otherwise a "flat" sequence of true/false of the same length as the input argument. Note there are no known valid uses of the sq_int() routine, as yet.