I'm running the following code on Emacs Lisp Interaction:
(defun square (x) (* x x))
(square (square (square 1001)))
which is giving me 1114476179152563777. However, the ((1001^2)^2)^2 is actually 1008028056070056028008001.
How is this possible?
#Barmar's answer is accurate for Emacs versions < 27.
In Emacs 27 bignum support has been added. NEWS says:
** Emacs Lisp integers can now be of arbitrary size.
Emacs uses the GNU Multiple Precision (GMP) library to support
integers whose size is too large to support natively. The integers
supported natively are known as "fixnums", while the larger ones are
"bignums". The new predicates 'bignump' and 'fixnump' can be used to
distinguish between these two types of integers.
All the arithmetic, comparison, and logical (a.k.a. "bitwise")
operations where bignums make sense now support both fixnums and
bignums. However, note that unlike fixnums, bignums will not compare
equal with 'eq', you must use 'eql' instead. (Numerical comparison
with '=' works on both, of course.)
Since large bignums consume a lot of memory, Emacs limits the size of
the largest bignum a Lisp program is allowed to create. The
nonnegative value of the new variable 'integer-width' specifies the
maximum number of bits allowed in a bignum. Emacs signals an integer
overflow error if this limit is exceeded.
Several primitive functions formerly returned floats or lists of
integers to represent integers that did not fit into fixnums. These
functions now simply return integers instead. Affected functions
include functions like 'encode-char' that compute code-points, functions
like 'file-attributes' that compute file sizes and other attributes,
functions like 'process-id' that compute process IDs, and functions like
'user-uid' and 'group-gid' that compute user and group IDs.
and indeed using my 27.0.50 build:
(defun square (x) (* x x))
square
(square (square (square 1001)))
1008028056070056028008001
Emacs Lisp doesn't implement bignums, it uses the machine's integer type. The range of integers it supports is between most-negative-fixnum and most-positive-fixnum. On a 64-bit system, most-positive-fixnum will be 261-1, which has about 20 decimal digits.
See Integer Basics in the Elisp manual.
The correct result of your calculation is 25 digits, which is much larger than this. The calculation overflows and wraps around. It should be correct modulo 262.
You could use floating point instead. It has a much larger range, although very large numbers lose precision.
(square (square (square 1001.0)))
1.008028056070056e+24
Related
As any secondary math student can attest, pi is irrational.
And yet:
Welcome to Racket v5.3.6.
> pi
3.141592653589793
> (rational? pi)
#t
Is this because the representation of pi, in the underlying machine's floating point format, is of limited precision and therefore can always be expressed as some p/q where q is 10^n, and n is the representational precision ?
If so, how could any number thrown about by Racket (or other similarly-behaving scheme) ever be considered anything but rational? And hence, why bother with the rational? function?
UPDATE: Even (rational? (sqrt 3)) reports #t
The number returned by pi is rational because the documentation says so. Specifically it says:
All numbers are complex numbers. Some of them are real numbers, and all of the real numbers that can be represented are also rational numbers, except for +inf.0 (positive infinity), +inf.f (single-precision variant), -inf.0 (negative infinity), -inf.f (single-precision variant), +nan.0 (not-a-number), and +nan.f (single-precision variant). Among the rational numbers, some are integers, because round applied to the number produces the same number.
So your hunch is right. All representable real numbers are indeed rational (except for the infinities and NaNs) because, yes, numbers are stored in fixed-size registers so the machine isn't going to store an irrational number.
As to why the Racket designers bothered with a rational? function, that is a good question. Many languages like Julia and Clojure have a real, actual, honest-to-goodness rational datatype. Racket doesn't, so, as you suspect, it does seem silly to define a near-complete subset of the reals as rationals.
But you know, it just may be convenient to have a way to talk about a non-NaN, non-Infinity value. I would have called it finite, but Racket calls it rational.
I have to run some computations in Racket that I have never used before.
How do I force it to calculate sth in single or half (if it has those) precision floats?
I figured out how to make it compute in big floats:
(bf/ (bf 1) (bf 7))
I know that the abbreviation for floats (double precision) is fl. I cannot figure out the right abbreviation for single floats though.
The 'bigfloat' package you refer to are for arbitrary precision floating point numbers. You're very unlikely to want these, as you point out.
It sounds like you're looking for standard IEEE 64-bit floating point numbers. Racket uses these by default, for all inexact arithmetic.
So, for instance:
(/ 1 pi)
produces
0.3183098861837907
One possible tripper-upper is that when dividing two rational numbers, the result will again be a rational number. So, for instance,
(/ 12347728 298340194)
produces
6173864/149170097
You can force inexact arithmetic either by using exact->inexact (always works), or by ensuring that your literals end with decimals (unless you're using the htdp languages).
So, for instance:
(/ 12347728.0 298340194.0)
produces
0.04138808061511148
Let me know if this doesn't answer your question....
I am tryin to retrieve the minimum value of integer in lisp. I found
most-negative-fixnum
variable that should represent the lowest possible number. whatever i try doing with it is throws error
Variable `MOST-NEGATIVE-FIXNUM' is unbound.
Is there any specific way how to get the value of variables in lisp? My research about this is without results.
Thanks
It should work as follows, using for example SBCL as an implementation of Common Lisp:
CL-USER> (lisp-implementation-type)
"SBCL"
CL-USER> (lisp-implementation-version)
"1.3.12.51-868cff4"
CL-USER> most-negative-fixnum
-4611686018427387904
[...] variable that should represent the lowest possible number
That would be the lowest possible fixnum. You have big numbers too:
CL-USER> (* 10000 most-negative-fixnum)
-46116860184273879040000
Since Common Lisp has bignum as a part of its specifications there are no limit to how low numeric value you can have from the language point of view.
Since machines have finite memory you will experience that there is a limit to how low the numbers your machine can have. It's not possible for an implementation to know this number or show it to you without actually trying to make it or perhaps the implementation has some ideas of th eoverhead. Without overhead you can use your available memory in bytes as an estimate and you'll have 8 bits per available byte. Eg my machine has about 11GB available so I guess I can use 10GB as the actual storage and sign, ie. 80G bits for the actual number. -2^80G+1 or ~-10^2900000000. You won't be able to print it since you have no available memory.
When generating random integers in Racket using the random function, Racket requires the argument to be a number between 1 and 4294967087. I was just wondering, where does that 4294967087 number come from, and why is it the maximum random number that Racket can generate?
It's close, but not exactly equal, to the maximum value of an unsigned 32-bit integer (4294967295). I assume there must be some reason why such a specific number was chosen?
It is the largest safe prime that is still smaller than 232-1. It is part of the original implementation of the MRG32k3a algorithm by Pierre L'Ecuyer.
The significance of this number is explained in his paper "Good Parameter Sets for Combined Multiple Recursive Random Number Generators", which is available on the papers website of L'Ecuyer (as a postscript file), and as a PDF at http://pubsonline.informs.org/doi/abs/10.1287/opre.47.1.159 . The reference implementation of the MRG32k3a algorithm is also available there: http://www.iro.umontreal.ca/~lecuyer/myftp/papers/combmrg2.c
In this paper, L'Ecuyer analyzed multiple recursive random number generators and did exhaustive searches for parameter sets that caused the generators to have desirable properties: Long period, good distribution of numbers, efficient implementation...
The value in question (which is referred to as 231-209 in the paper) is part of a parameter set of the MRG32k3a algorithm that has these properties.
(but admittedly, I didn't do the maths...)
It is the largest safe prime less than 2^32. They use this number because that gives their pseudo-random number generator the largest possible period.
A safe prime number p is a prime for which (p - 1)/2 also is prime. This other prime is called a Sophie Germain prime.
i'm trying to get a first lisp program to work using the CLISP implementation, by typing
(print (mod (+ (* 28433 (expt 2 7830457) 1)) (expt 10 10))))
in the REPL.
but it gives me *** - overflow during multiplication of large numbers. i thought lisp features arbitrary size/precision. how could that ever happen then?
Lisp's bignums may hold really large numbers, but they too have their limits.
In your case, you can combine exponentiation and modulus into a single procedure, e.g. as in http://en.wikipedia.org/wiki/Modular_exponentiation#Right-to-left_binary_method.
According to http://clisp.cons.org/impnotes/num-concepts.html the maximum size for a bignum is (2^2097088 - 1) and your 2^7830457 is much larger than that.
Perhaps you can look at breaking down that number - perhaps separate out a number of smaller 2^X factors...
Chances are there's a better way to solve the problem. I haven't made it that far on PE, but I know the few that I've done so far tend to have "aha!" solutions to problems that seem out of a computer programs range.
This one especially - 2^7830457 is a huge number -- try (format t "~r" (expt 2 160)). You might try to look at the problem in a new light and see if there's a way to look at it that you haven't thought of.
Lisp is a family of languages with dozens of dialects and hundreds of different implementations.
Computers have finite memory. Programs under some operating systems may have limitations about the memory size. Different Common Lisp implementations use different numeric libraries.
You may want to consult your CLISP manual for its limitations of its various data types.
CLisp provided the function "mod-expt" (or EXT:mod-expt)
[1]> (mod-expt 2 1000000 59)
53
which is pretty fast. And for your purpose that works.