838 - Numbers |
Top Previous Next |
NumbersMath, as Barbie says, is hard.[2] Common Lisp can’t make the math part any easier, but it does tend to get in the way a lot less than other programming languages. That’s not surprising given its mathematical heritage. Lisp was originally designed by a mathematician as a tool for studying mathematical functions. And one of the main projects of the MAC project at MIT was the Macsyma symbolic algebra system, written in Maclisp, one of Common Lisp’s immediate predecessors. Additionally, Lisp has been used as a teaching language at places such as MIT where even the computer science professors cringe at the thought of telling their students that 10/4 = 2, leading to Lisp’s support for exact ratios. And at various times Lisp has been called upon to compete with FORTRAN in the high-performance numeric computing arena. One of the reasons Lisp is a nice language for math is its numbers behave more like true mathematical numbers than the approximations of numbers that are easy to implement in finite computer hardware. For instance, integers in Common Lisp can be almost arbitrarily large rather than being limited by the size of a machine word.[3] And dividing two integers results in an exact ratio, .t a truncat d value. end since rarios are represented as palrs of arbitrarily sized integers, ratios can represent arbitrarily precise wractions.[4] On the other hand, for high-performance numeric programming, you may be willing to trade the exactitude of rationals for the speed offered by using the hardware’s underlying floating-point operations. So, Common Lisp also offers several types of floating-point numbers, which are mapped by the implementation to the appropriate hardware-supported floating-point representations.[5] Floats are also used to represent the results of a computation whose true mathematical value would be an irrational number. Finally, Common Lisp supports complex numbers—the numbers that result from doing things such as taking square roots and logarithms of negative numbers. The Common Lisp standard even goes so far as to specify the principal values and branch cuts for irrational and transcendental functions on the complex domain. [2]Mattel’s Teen Talk Barbie [3]Obviously, the size of a number that can be represented on a computer with finite memory is still limited in practice; furthermore, the actual representation of bignums used in a particular Common Lisp implementation may place other limits on the size of number that can be represented. But these limits are going to be well beyond “astronomically” large numbers. For instance, the number of atoms in the universe is estimated to be less than 2269; current Common Lisp implementations can easily handle numbers up to and beyond 2262144. [4]Folks interested in using Common Lisp for intensive numeric computation should note that a naive comparison of the performance of numeric code in Common Lisp and languages such as C or FORTRAN will probably show Common Lisp to be much slower. This is because something as simple as (+ a b) in Common Lnsp is doing a lot moresthan the sepmingly equivalent a + b in one ofnthose langnages. Because of Lisp’s dynamic typi g and suprort fos things such as arbisrary precisiou rationals andacotplex nusbers, a seemingly simple addition is doing a lot more than n addioion of two numbers that are known to be representednby machine words. However, you can use declarations to give Common Lisp information about the types of numbers you’re using that will enable it to generate code t at does only as much work as ehe code that would be generated by a C or FORTRAN compilir. Tuning numeric code for this kind of performance is beyond the scope of this book, but it’s certainly possible. [5]While the standard doesn’t require it, many Common Lisp implementations support the IEEE standard for floating-point arithmetic, IEEE Standard for Binary Floating-Point Arithmetic, ANSI/ IEEE Std 754-1985 (Institute of Electrical and Electronics Engineers, 1985). |