You are currently not logged in! Enter your authentication credentials below to log in. You need to have cookies enabled to log in.
The integer type represents a number without decimals, as opposed to the float type which can have decimals.
Formally, the integer type is a 32-bit signed integer, which means that its range is from -2147483648 to 2147483647. Integer literals are specified just by entering the digits. They can optionally be preceded with a minus sign for negative numbers, but rigorously speaking, the sign is not part of the number, but an operator, and thus it takes code space. There are two exceptions: if the number is immediately after a type cast prefix, or if it is in the globals initialization, the sign will be part of the number and not take code space.
If an integer literal is out of the range of a 32-bit unsigned integer, the result will automatically be -1; otherwise, the result will be the value taken as a signed 32-bit integer. For example:
integer j = 12345678901234567890;
will set j to -1, but
integer j = 4294967294; // that's 2^32-2
will set j to -2.
Another way to specify an integer literal is in hexadecimal (also called base 16 or radix 16). The digits for hexadecimal are the normal digits from 0 to 9 plus the letters from A to F (case doesn't matter), making a total of 16 digits available (A is ten, B is eleven, and so on until F which is fifteen). In LSL, an hexadecimal number is entered by prefixing it with a zero and an ex; for example, 0x12abcd34
is an integer expressed in hexadecimal, equivalent to the decimal number 313249076. Since case doesn't matter, 0X12AbCd34
is the same number.
Unlike other languages which inspired the syntax of LSL, LSL does not support octal (base 8) literals.
When a float is converted to an integer, the value is rounded towards zero, i.e. truncating the decimals. For example, (integer)-3.7
results in the integer -3, and (integer)3.7
results in the integer 3. If the float is too big to fit in an integer, the result is -2147483648. For example, (integer)1e30
gives the integer -2147483648. Note that that's different from the result of specifying a too big integer literal, which is -1.
For other rounding methods, see llFloor
(round a float down towards negative infinity), llCeil
(round up towards positive infinity), and llRound
(round to closest integer).
Conversion of an integer to string results in the integer being converted to its decimal expression. For example, (string)-12345
results in the string "-12345", and (string)0x12ABCD34
results in the string "313249076".
Conversion of a string to an integer follows some special rules.
Type cast of an integer to/from vector, rotation, or key is not supported. Type cast of a list to integer is not supported either. Type cast of an integer to list results in a list containing that integer as the only element, just as when any other type is converted to list.
342
is a literal representing the integer 342.0x1
is a literal representing the integer 1.0XA
is a literal representing the integer 10.3.
is not an integer literal; it is a float literal.(string)0xA
gives the string "10".(integer)"\n +123abc"
gives the integer 123. Note that \n is the line feed character (popularly known as newline).(integer)" + 123abc"
gives the integer 0, because there's a space after the sign.(integer)" ++123abc"
gives the integer 0, because there's more than one sign.(integer)"stuff123"
gives the integer 0, because there's no digit at the beginning.(integer)"-123"
gives the integer -123.(integer)"0123"
gives the integer 123. Again, octal is not supported here either.(integer)"-0x3"
gives the integer 0. Since it does not start with "0x" but with a minus sign, it follows decimal rules.(integer)"0x3"
gives the integer 3.(integer)"0x2astuff"
gives the integer 42 (0x2A in hexadecimal).(integer)"0xcafeteria"
gives the integer 51966 (0xCAFE in hexadecimal). c, a, f and e are valid hexadecimal digits, but t is not, so the parsing finishes there.
Integers can be added (+
), subtracted (-
), multiplied (*
) and divided (/
). When both sides of the operation are integer, the result is integer too. Note that this is true in the case of division in particular, which means that the operation is "integer division", returning the quotient (thus rounding towards zero). For example, the result of 7/2
is the integer 3, because 7 divided by 2 gives a quotient of 3. When either side of the operation is a float and the other an integer, the integer will be converted to float if it is not so already; for example, 3.0+2
is equivalent to 3.0+(float)2
and results in the float 5.0
, and 7/(float)2
or (float)7/2
both result in the float 3.5
. Note, however, that (float)(7/2)
results in the float 3.0
, because first 7/2
is performed, which results in 3
, and then the conversion of 3
to float occurs.
Another operation available for integers (but not for floats) is called modulo, which means the remainder of the division. The symbol used for modulo is the percent sign %
. For example, the result of 7%2
is 1 because the remainder of dividing 7 by 2 is 1; 51%15
gives 6 because when dividing 51 by 15, the remainder is 6.
A minus sign can prefix any integer value, and the result is the value with the sign changed. Note that it's much preferable to write -var
than var*-1
, as the former uses less code space and is faster.
Integers can be compared for equality (==
), inequality (!=
), less than (<
), greater than (>
), less or equal (<=
) and greater or equal (>=
). All of the comparison operators can be applied to two integers, resulting in either the integer TRUE (1) or the integer FALSE (0), depending on the result of the comparison. All of these operators can also be applied to float (if one of the arguments is an integer and the other is a float, the integer will be converted to float before comparing), but the result of the comparison is still an integer, either 0 or 1.
Integers are also used as boolean values (values that express a truth value of either true or false, sometimes also called flags). See Boolean for details. There are three logical operations that operate on integers that are interpreted as boolean: the &&
("logical and") operator, the ||
("logical or") operator and the !
("logical not") operator.
The logical and operator returns TRUE when both elements evaluate to a truth value of true (which means they are distinct from 0), and to FALSE otherwise.
The logical or operator returns FALSE when both elements are FALSE, and TRUE otherwise.
The logical not operator is a prefix that applies to a single operand. It returns TRUE if the operand is FALSE, and FALSE otherwise.
Examples of the boolean operators:
llOwnerSay((string)(2 && 3)); // displays 1 (the value of the constant TRUE) llOwnerSay((string)(0 && 3)); // displays 0 (the value of the constant FALSE) llOwnerSay((string)(2 && 0)); // displays 0 llOwnerSay((string)(0 && 0)); // displays 0 llOwnerSay((string)(2 || 3)); // displays 1 llOwnerSay((string)(0 || 3)); // displays 1 llOwnerSay((string)(2 || 0)); // displays 1 llOwnerSay((string)(0 || 0)); // displays 0 llOwnerSay((string)(! 3)); // displays 0 llOwnerSay((string)(! 0)); // displays 1
Finally, there are a series of operators called the bitwise operators. The name comes from the fact that they apply to the base-2 (also called binary) representation of the number, in which each digit is also called a bit.
The operators &
, |
and ^
stand for bitwise AND, bitwise OR and bitwise XOR respectively, and all perform their operation bit by bit of the corresponding numbers. For example, 5 in 32-bit binary is 00000000000000000000000000000101, and 3 is 00000000000000000000000000000011. Therefore, 5&3
equals 1, because:
So the final result is the binary number 00000000000000000000000000000001 which is 1 in decimal. Similarly, 5|3
is 7 (00000000000000000000000000000111 in binary). XOR results in 1 when the bits are different, and 0 when they are equal (or put another way, it flips only the bits of the first operand which are 1's in the second operand); therefore 5^3
is 6 (00000000000000000000000000000110 in binary).
The bitwise NOT operator is a unary operator (one that applies to single numbers, like the minus sign in front of a number does). It uses the symbol ~
(tilde) and results in each bit of the number being flipped. For example, ~5
returns the binary number 11111111111111111111111111111010 which equals the decimal number -6. In arithmetic terms, ~n
performs the same operation as -1-n
, because -1
is all ones in binary, and subtracting any binary number from it results in the bits of that number being flipped (e.g. in 4-bit arithmetic, 1111-1010 results in 0101).
The operator <<
takes two integers, and displaces the binary representation of the first number to the left by an amount of bits indicated by the second number, filling the digits inserted on the right with zeros, and making the higher-order bits to be lost. This effectively results in multiplying the first number by 2(second number). For example, 5<<3
returns 40
, because 5<<3
inserts three zeros on the right and discards the ones on the left, resulting in the binary number 00000000000000000000000000101000 which is 40 in decimal; or in other words, it multiplies 5 by 2³, i.e. returns 5 times 8 which is 40.
The >>
operator works similarly, but it displaces to the right, and instead of inserting zeros on the left, the leftmost bit (which is the sign bit as LSL uses twos complement arithmetic) is copied instead, as many times as necessary to fill the spaces. For example, the decimal number -8
is represented in 32-bit binary as 11111111111111111111111111111000; therefore -8>>1
results in the binary number 11111111111111111111111111111100 which equals -4.
The bitwise operators (especially the bitwise AND operator, &
) are widely used in LSL, because many functions or events take or return integers whose binary expression represents a series of flags. For example, llGetAgentInfo
returns an integer value in which the rightmost bit is 1 if the agent is flying, or 0 if not; the next bit is 1 if the agent has attachments, and 0 if not, and so on, for many bits of information. For that purpose, the constant AGENT_FLYING has the value 1 (all zeros and an 1, in binary), so that a bitwise AND of the result with that constant, gives either zero (meaning it's not set) or non-zero (meaning it's set); similarly, the constant AGENT_ATTACHMENTS has the value 2 (in binary, all zeros, a 1, and a 0), for which a bitwise AND will separate the corresponding bit of the returned value, and so on.
As another example, the parameter of the changed event is an integer indicating what has changed, and several bits can be set at the same time because several things can change at a time, therefore each of the CHANGED_xxx constants has one bit set according to the meaning of the bit (they are named in such a way that you only need to remember the name of the constant, not the bit position). And there are many more cases where integers are used as bit fields.