.. _math: **** Math **** Numbers in Lasso are stored and manipulated using the :type:`decimal` and :type:`integer` types. This chapter details the operators and methods that can manipulate decimal and integer values and to perform mathematical operations. Each of these methods is described in detail in the sections that follow; however, the Lasso Reference is the primary documentation source for Lasso operators and methods. Creating Integer Objects ======================== The :type:`integer` type represents whole number values. Basically, zero and any positive or negative number that does not contain a decimal point is an integer value in Lasso. Examples include ``-123`` or ``456``. Integer objects may also be expressed in hexadecimal notation such as ``0x1A`` or ``0xff``. .. type:: integer .. method:: integer() .. method:: integer(obj::any) The creator method for integer converts any object to an integer. If the type for the object being converted does not easily represent an integer, "0" will be returned. Explicit Integer Conversion --------------------------- Strings that contain numeric data can be converted to integer objects using the `integer` creator method. The string must start with a numeric value. In the following examples the integer ``123`` is the result of each explicit conversion. Only the first integer found in the string ``'123 and then 456'`` is recognized:: integer('123') // => 123 integer('123 and then 456') // => 123 Decimals that are converted to an integer are rounded to the nearest integer:: integer(123.0) // => 123 integer(123.999) // => 124 Formatting Integer Objects ========================== Integer objects can be formatted for display using the `integer->asString` method detailed below. .. note:: Integers and decimals have no state, so they cannot carry around formatting information. The `integer->asString` method replaces the functionality of the ``integer->setFormat`` method from previous versions of Lasso. .. member: integer->asString(p0::string, p1::string, p2::string) .. member:: integer->asString(\ -hexadecimal::boolean= ?, \ -padding::integer= ?, \ -padChar::string= ?, \ -padRight::boolean= ?, \ -groupChar::string= ?) Returns a string representation of the integer value formatted as specified by the parameters passed to the method. If no parameters are passed to the method, the string will be the integer value output in base 10. :param boolean -hexadecimal: If set to "true", the integer will output in hexadecimal notation. :param integer -padding: Specifies the desired length for the output. If the formatted number is less than this length then the number is padded. :param string -padChar: Specifies the character to insert if padding is required. Defaults to a space. :param boolean -padRight: Set to "true" to pad the right side of the output. By default, padding is appended to the left side of the output. :param string -groupChar: Specifies the character to use for thousands grouping. Defaults to empty. Format an Integer as a Hexadecimal Value ---------------------------------------- The following example creates a variable with an integer value and then outputs that value in base 16:: local(my_int) = 255 #my_int->asString(-hexadecimal) // => ff Integer Bitwise Methods ======================= Bitwise operations can be performed with Lasso's integer objects. These operations can examine and manipulate binary data. They can also be used for general purpose binary set operations. Integer literals in Lasso can be specified using hexadecimal notation. This can greatly aid in constructing literals for use with the bitwise operation. For example, ``0xff`` is the integer literal ``255``. .. member:: integer->bitAnd(i::integer) Performs a bitwise "and" operation between each bit in the base integer and the integer parameter, returning the result. .. member:: integer->bitOr(i::integer) Performs a bitwise "or" operation between each bit in the base integer and the integer parameter, returning the result. .. member:: integer->bitXOr(i::integer) Performs a bitwise "exclusive or" operation between each bit in the base integer and the integer parameter, returning the result. .. member:: integer->bitNot() Returns the result of flipping every bit in the base integer. .. member:: integer->bitShiftLeft(i::integer) Returns the result of shifting the bits in the base integer left by the number specified in the integer parameter. .. member:: integer->bitShiftRight(i::integer) Returns the result of shifting the bits in the base integer right by the number specified in the integer parameter. .. member:: integer->bitClear(i::integer) Returns the result of clearing the bit specified in the integer parameter. .. member:: integer->bitFlip(i::integer) Returns the result of flipping the bit specified in the integer parameter. .. member:: integer->bitSet(i::integer) Returns the result of setting the bit specified in the integer parameter. .. member:: integer->bitTest(i::integer) Returns "true" if the bit specified in the integer parameter is 1, otherwise returns "false". .. note:: Integers are by-value objects and are immutable, so it is not possible to change their value. This is in contrast to previous versions of Lasso, where these bit methods modified the integer in-place. Perform a Bitwise OR -------------------- In the following example the boolean "or" of ``0x02`` and ``0x04`` is calculated and returned in hexadecimal notation:: local(bit_set) = 0x02 #bit_set->bitOr(0x04)->asString(-hexadecimal) // => 6 Shift Bits to the Left ---------------------- In the following example, ``0x02`` is shifted left by three places and output in hexadecimal notation:: local(bit_set) = 0x02 #bit_set = #bit_set->bitShiftLeft(3) #bit_set->asString(-hexadecimal) // => 10 Set and Test a Specified Bit ---------------------------- In the following example, the second bit of an integer is set and then tested:: local(bit_set) = 0 #bit_set = #bit_set->bitSet(2) #bit_set->bitTest(2) // => true Creating Decimal Objects ======================== The :type:`decimal` type represents real or floating point numbers. Basically, 0.0 or any positive or negative number that contains a decimal point is a decimal object in Lasso. Examples include ``-123.0`` and ``456.789``. Decimal values can also be written in exponential notation such as ``1.23e2`` which is equivalent to ``1.23`` times ``10^2`` or ``123.0``. .. type:: decimal .. method:: decimal() .. method:: decimal(i::integer) .. method:: decimal(d::decimal) .. method:: decimal(s::string) .. method:: decimal(b::bytes) .. method:: decimal(n::null) .. method:: decimal(n::void) The creator methods for the :type:`decimal` type converts :type:`integer`, :type:`string`, :type:`bytes`, :type:`null`, and :type:`void` objects to a decimal value. The precision of a decimal value when converted to a string is always displayed as six decimal places even though the actual precision of the number may vary based on the size of the number and its internal representation. The output precision of decimal numbers can be controlled using the `decimal->asString` method described later in this chapter. Implicit Decimal Conversion --------------------------- Integer values are converted to decimal values automatically if they are used as a parameter to an arithmetical operator in conjunction with a decimal value. The following example shows how the integer ``123`` is automatically converted to a decimal value because the other parameter of the ``+`` operator is the decimal value ``456.0``:: 456.0 + 123 // => 579.0 The following example shows how a variable with a value of "123" is automatically converted to a decimal value:: local(number) = 123 456.0 + #number // => 579.0 Explicit Decimal Conversion --------------------------- Strings containing numeric data can be converted to the :type:`decimal` type using the `decimal` creator method. The string must start with a numeric value. In the following examples the number ``123.0`` is the result of each explicit conversion. Only the first decimal value found in the string ``'123 and then 456'`` is recognized:: decimal('123') // => 123.0 decimal('123.0') // => 123.0 decimal('123 and then 456') // => 123.0 Integers that are converted to decimals simply have a decimal point appended. The value of the number does not change. :: decimal(123) // => 123.0 Formatting Decimal Objects ========================== Decimal objects can be formatted for display using the `decimal->asString` method detailed below. .. note:: Integers and decimals have no state, so they cannot carry around formatting information. The `decimal->asString` method replaces the functionality of the ``decimal->setFormat`` method from previous versions of Lasso. .. member: decimal->asString(p0::string, p1::string, p2::string) .. member:: decimal->asString(\ -decimalChar::string= ?, \ -groupChar::string= ?, \ -precision::integer= ?, \ -scientific::boolean= ?, \ -padding::integer= ?, \ -padChar::string= ?, \ -padRight::boolean= ?) Returns a string representation of the decimal value formatted as specified by the parameters passed to the method. If no parameters are passed to the method, the string will be the decimal value with six places of precision. :param string -decimalChar: The character that should be used for the decimal point. Defaults to a period. :param string -groupChar: The character that should be used for thousands grouping. Defaults to an empty string. :param integer -precision: The number of places after the decimal point that should be output. The default is 6. :param boolean -scientific: Set to "true" to force output in exponential notation. Default to "false", so decimals are only output in exponential notation if required. :param integer -padding: Specifies the desired length for the output. If the formatted number is less than this length then the number is padded. :param string -padChar: Specifies the character that will be inserted if padding is required. Defaults to a space. :param boolean -padRight: Set to "true" to pad the right side of the output. By default, padding is prepended to the left side of the output. Format a Decimal Number as U.S. Currency ---------------------------------------- The following example outputs a decimal value as if it were U.S. currency by setting the precision to "2". For readability, it also sets a comma as the grouping character. :: local(dollar_amt) = 1234.56 #dollar_amt->asString(-precision=2, -groupChar=',') // => 1,234.56 Arithmetical Operations ======================= The easiest way to manipulate integer and decimal objects is to use arithmetical operators. The sections below detail all the operators that can be used with integer and decimal values. See the :ref:`operators` chapter for further documentation of how these operators are used. Basic Arithmetical Operators ---------------------------- Each basic operator takes two parameters, one to its left and the other to its right. If either of the parameters is a decimal then the result will be a decimal value. Some of the operators can also be used to perform string operations. If either of the parameters is a string value then the string operation defined by the operator will be performed rather than the arithmetical operation. .. tabularcolumns:: llL .. _math-operators: .. table:: Arithmetical Operators ======== ============== ===================================================== Operator Name Description ======== ============== ===================================================== ``+`` Addition Adds two parameters. ``-`` Subtraction Subtracts the right parameter from the left parameter. ``*`` Multiplication Multiplies two parameters. ``/`` Division Divides the left parameter by the right parameter. ``%`` Modulo Produces the remainder of dividing the left parameter by the right parameter. ======== ============== ===================================================== Using Arithmetical Operators ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Two numbers can be added using the ``+`` operator. The output will be a decimal value if either of the parameters are a decimal value. :: 100 + 50 // => 150 100 + -12.5 // => 87.500000 The difference between two numbers can be calculated using the ``-`` operator. The output will be a decimal value if either of the parameters are a decimal value. Note that in the second instance, when subtracting a negative number, the two ``-`` operators must be separated by a space so as not to be confused with the ``--`` operator. :: 100 - 50 // => 50 100 - -12.5 // => 112.500000 Two numbers can be multiplied using the ``*`` operator. The output will be a decimal value if either of the parameters are a decimal value. :: 100 * 50 // => 5000 100 * -12.5 // => -1250.000000 Arithmetical Assignment Operators --------------------------------- Each of the operators takes two parameters, one to its left and the other to its right. The first parameter must be a variable that holds an integer, decimal, or string. The second parameter can be an integer, decimal, or string literal. The result of the operation is calculated and then stored back in the variable specified as the left-hand parameter. .. tabularcolumns:: llL .. _math-assignment-operators: .. table:: Arithmetical Assignment Operators ======== =============== ==================================================== Operator Name Description ======== =============== ==================================================== ``=`` Assign Assigns the right parameter to the variable designated by the left parameter. ``+=`` Add-assign Adds the right parameter to the value of the left parameter and assigns the result to the variable designated by the left parameter. ``-=`` Subtract-assign Subtracts the right parameter from the value of the left parameter and assigns the result to the variable designated by the left parameter. ``*=`` Multiply-assign Multiplies the value of the left parameter by the value of the right parameter and assigns the result to the variable designated by the left parameter. ``/=`` Divide-assign Divides the value of the left parameter by the value of the right parameter and assigns the result to the variable designated by the left parameter. ``%=`` Modulo-assign Assigns the value of the left parameter modulo the right parameter to the variable designated by the left parameter. ======== =============== ==================================================== Using Arithmetical Assignment Operators ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A variable can be assigned a new value using the assignment operator (``=``). The following example shows how to define an integer variable and then set it to a new value, which is then output:: local(my_variable) = 100 #my_variable = 123456 #my_variable // => 123456 A variable can be used as a collector by adding new values using the ``+=`` operator. The following example shows how to define an integer variable, add several values to it, then output the final value:: local(my_variable) = 100 #my_variable += 123 #my_variable += -456 #my_variable // => -233 Arithmetical Equality Operators ------------------------------- Each of the arithmetical equality operators takes two parameters, one to its left and the other to its right. .. tabularcolumns:: llL .. _math-equality-operators: .. table:: Arithmetical Equality Operators ======== ================ =================================================== Operator Name Description ======== ================ =================================================== ``==`` Equal Returns "true" if the parameters are equal. ``!=`` Not equal Returns "true" if the parameters are not equal. ``<`` Less Returns "true" if the left parameter is less than the right parameter. ``<=`` Less or equal Returns "true" if the left parameter is less than or equal to the right parameter. ``>`` Greater Returns "true" if the left parameter is greater than the right parameter. ``>=`` Greater or equal Returns "true" if the left parameter is greater than or equal to the right parameter. ======== ================ =================================================== Using Arithmetical Equality Operators ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Two numbers can be compared for equality using the equality (``==``) and inequality (``!=``) operators. The result is a boolean "true" or "false". Integers are automatically converted to decimal values when compared with decimals. :: 100 == 123 // => false 100.0 != -123.0 // => true 100 == 100.0 // => true 100.0 != -123 // => true Numbers can be compared using the relative equality operators (``<``, ``<=``, ``>``, ``>=``). The result is a boolean "true" or "false". :: -37 > 0 // => false 100 < 1000.0 // => true Basic Math Methods ================== Lasso contains many methods that can perform mathematical functions. The functionality of some of these methods overlaps the functionality of the mathematical operators. It is recommended that you use the equivalent operator when one is available. .. method:: math_abs(value) Returns the absolute value of the parameter. .. method:: math_add(value, ...) Returns the sum of all parameters. .. method:: math_ceil(value) Returns the next integer greater than the parameter. .. method:: math_convertEuro(value, euroTo::string) Converts between the Euro and other European Union currencies. .. method:: math_div(value, ...) Divides each of the parameters in order from left to right. .. method:: math_floor(value) Returns the next integer less than the parameter. .. method:: math_max(value, ...) Returns the maximum of all parameters. .. method:: math_min(value, ...) Returns the minimum of all parameters. .. method:: math_mod(value, factor) Returns the value of the first parameter modulo the second parameter. .. method:: math_mult(value, ...) Returns the product of multiplying each of the parameters together. .. method:: math_random()::decimal .. method:: math_random(upper::integer, lower=0)::integer .. method:: math_random(upper::decimal, lower=0.0)::decimal .. method:: math_random(-upper, -lower)::integer If called with no parameters, returns a random number between 0.0 and 1.0. Can also take two parameters, with the first as the upper bound for the random number, and the second as the lower bound. If the first parameter is an integer, an integer will be returned, and if it is a decimal, then a decimal will be returned. Can also be called with ``-upper`` and ``-lower`` keyword parameters and will then return an integer value regardless of the types of the objects passed as parameters. When returning integer values, `math_random` returns a maximum 32-bit value. The range of returned integers is approximately between +/- 2,000,000,000. .. method:: math_rint(value) Returns a decimal value rounded to the nearest integer. .. method:: math_roman(value) Returns a string representing the number passed in as a Roman numeral. .. method:: math_round(value, factor) Rounds the first parameter to the precision specified by the second parameter. Using Basic Math Methods ------------------------ The following are all examples of using basic math methods to calculate the results of various mathematical operations:: math_add(1, 2, 3, 4, 5) // => 15 math_add(1.0, 100.0) // => 101.000000 math_sub(10, 5) // => 5 math_div(10, 9) // => 1 math_div(10, 8.0) // => 1.250000 math_max(100, 200) // => 200 Round to an Integer ------------------- Decimals can be rounded to an integer using the `integer` creator method, the `math_floor` method to round to the next lowest integer, or the `math_ceil` method to round to the next highest integer:: integer(37.6) // => 38 math_floor(37.6) // => 37 math_ceil(37.6) // => 38 Round to Nearest Integer ------------------------ Decimals can be rounded to the nearest integer using the `math_rint` method. This method rounds the decimal, but does not convert it to an integer:: math_rint(37.6) // => 38.000000 Round to a Specified Precision ------------------------------ Numbers can be rounded to arbitrary precision using the `math_round` method with a decimal parameter. The second parameter should be of the form ``0.01``, ``0.0001``, ``0.000001``, etc. :: math_round(3.1415926, 0.0001) // => 3.141600 math_round(3.1415926, 0.001) // => 3.142000 math_round(3.1415926, 0.01) // => 3.140000 math_round(3.1415926, 0.1) // => 3.100000 Numbers can be rounded to an even multiple of another number using the `math_round` method with an integer parameter. The integer parameter should be a power of 10. :: math_round(1463, 1000) // => 1000.000000 math_round(1463, 100) // => 1500.000000 math_round(1463, 10) // => 1460.000000 .. note:: If a rounded result needs to be shown to the user but the actual value stored in a variable does not need to be rounded, either the `integer->asString` or `decimal->asString` method can alter how the number is displayed. See the documentation of these methods earlier in this chapter for more information. Return a Random Integer Value ----------------------------- In the following example a random number between ``1`` and ``100`` is returned. The random number will be different each time the page is loaded. :: math_random(100, 1) // => 55 Return a Random Decimal Value ----------------------------- In the following example a random decimal number between ``0.0`` and ``1.0`` is returned. The random number will be different each time the page is loaded. :: math_random(1.0, 0.0) // => 0.532773 Return a Random Hex Color Value ------------------------------- In the following example a random hexadecimal color code is returned. The random number will be different each time the page is loaded. The range is from ``0`` to ``255`` to return two-digit hexadecimal values between ``00`` and ``FF``. :: local(color) = "#" + math_random(255,0)->asString(-hexadecimal, -padding=2, -padChar='0') + math_random(255,0)->asString(-hexadecimal, -padding=2, -padChar='0') + math_random(255,0)->asString(-hexadecimal, -padding=2, -padChar='0') 'Color' // => Color Trigonometry and Advanced Math Methods ====================================== Lasso provides a number of methods for calculating square roots, logarithms, and exponents, and performing trigonometric functions. .. method:: math_acos(value) Arc Cosine. Returns the value of taking the arc cosine of the passed parameter. The return value is in radians between "0" and "π". .. method:: math_asin(value) Arc Sine. Returns the value of taking the arc sine of the passed parameter. The return value is in radians between "-π/2" and "π/2". .. method:: math_atan(value) Arc Tangent. Returns the value of taking the arc tangent of the passed parameter. The return value is in radians between "-π/2" and "π/2". .. method:: math_atan2(value, factor) Arc Tangent of a Quotient. Returns the value of taking the angle in radians between the x-axis and coordinates passed to it. The return value is in radians between "-π" and "π". .. method:: math_cos(value) Cosine. Returns the value of taking the cosine of the passed parameter. .. method:: math_sin(value) Sine. Returns the value of taking the sine of the passed parameter. .. method:: math_tan(value) Tangent. Returns the value of taking the tangent of the passed parameter. .. method:: math_exp(value) Natural Exponent. Returns the value of taking *e* raised to the specified power. .. method:: math_ln(value) .. method:: math_log(value) Natural Logarithm. Returns the value of taking the natural log of the passed parameter. .. method:: math_log10(value) Base 10 Logarithm. Returns the value of taking the base 10 log of the passed parameter. .. method:: math_pow(value, factor) Exponent. Returns the value of taking the first parameter and raising it to the value of the second parameter. .. method:: math_sqrt(value) Square Root. Returns the positive square root of the passed parameter. The parameter passed to this method must be positive. Using Advanced Math Methods --------------------------- The following are examples of using some of these advanced math methods to calculate various mathematical operations:: math_pow(3, 3) // => 27 math_sqrt(100.0) // => 10.000000 math_acos(-1.0) // => 3.141593 math_exp(math_log(5)) // => 5.000000