If you've ever written a program in C, you'll know about static typing. When you declare a variable, you say what kind of variable it is. In Elisp, we've already seen that you can setq anything to a variable so that a variable that started out as a number may end up as a string. In a language standpoint, this is called "dynamic typing". Elisp uses "predicate" functions to determine the type of a variable. So, for numbers:
(numberp var) ; Returns t or nil based if var is a number or not
(integerp var) ; Returns t or nil based if var is a whole number (integer)
or not
(floatp var) ; Returns t or nil based if var is a decimal (floating-point
number) or not
(stringp var) ; Returns t or nil based if var is a string
These functions that end in "p" or "-p" are predicate functions. They're often used in conditional functions (cond, if, and others we'll see in section 4).
An important question arises early: if a user inputs a string that can be represented as a number, how do you convert a string to a number or vice-versa? The answer is pretty easy, actually:
(number-to-string var)
(string-to-number var)
Elisp's math functions are quick to learn, but ugly. If you want to add, subtract, multiply, or divide two numbers, you would respectively use functions like these:
(setq numA 3 numB 4) ; numA = 3, numB = 4
(+ numA numB) ; Returns 7
(- numA numB) ; Returns -1
(* numA numB) ; Returns 12
(/ numA numB) ; Returns 0
Zero? numA and numB are integers, so the result will be an integer as well. Adding some precision to numA or numB, the decimal precision is added to the quotient.
(setq numA 3.0 numB 4)
(/ numA numB) ; Here's the 0.75
The term "casting" is a common one in computer science— it's changing a value from one type to another. Instead of adding decimal points (which is weird), we can cast a value to another value, and the function name for that is usually the destination type of the casted value. That is, if you were casting from some other value to float, you'd use:
(setq numA 3 numB 4)
(/ (float numA) numB) ; There's your .75 again!
Elisp has lots of trig functions which work almost exactly as you would expect from sin, cos, and tan to their asin, acos, and atan counterparts. These accept radian values as arguments. Also, helping things along is the pi variable, which is predefined. Looking at this:
(message (number-to-string pi)) ; Prints 3.141592653589793
(setq someTheta (sin pi)) ; Sets someTheta to an infinitesimal
Of particular note, the atan function can take two arguments. This is like the "atan2" function in C. A widespread use for atan is to tell an angle between some point and the horizon through the origin, but the single-argument function has no notion of the quadrant of y/x, so this form comes about: atan y x. Unlike C and bretheren, in Elisp, there's only one atan function, but it can take one or two arguments.
Some other self-explanatory functions include: abs (for absolute value), exp (returns eval), and sqrt (returning √(val)), log10. Also of interest:
(setq someVal 10) ; Some value to play with
(log someVal) ; Returns log (base e) of 10
(log someVal 4) ; Returns log (base 4) of 10
(expt someVal 2) ; Returns someVal2
Another basic thing folks like to do with math is get random numbers... this is huge for making games. Elisp's random function takes a little getting used to. In C (and the like, as well as PovRay, oddly enough), two function calls are required to get "real" pseudorandom numbers: one to set the seed of the random number generator, and the other to actually get the number. Elisp works the same way, but both calls are made to the same function.
(random t) ; Call this ONCE in your code. Sets the RNG seed.
(random) ; Returns a number between 0 and 1,073,741,823 (on most systems)
(random 5) ; Returns a number between 0 and 4. MOST USEFUL!
So... one function for all your random needs. The last form in the above example (random N) where N is an integer greater than zero is probably the most useful function. It returns an integer between zero (inclusive) and N(exclusive).
Like the numberp and the like, there are also functions for comparing functions that return either "t" or nil based on the conditions of the arguments. These will be important in the control structures section, but I'll introduce them here since they're rather like the basic math operators:
(setq numA 4 numB 5) ; Set some values...
(> numA numB) ; nil
(< numA numB) ; t
(>= numA numB) ; nil
(<= numA numB) ; t
(= numA numB) ; nil
(/= numA numB); t
It may be worth mentioning that /= is inequality, which is rather non-standard among programming languages— it's != in C-derived languages, and <> in BASIC-like languages.