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.
Related
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
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.
While reading about Elias Gamma coding on wikipedia, I see it mentions that:
"Gamma coding is used in applications where the largest encoded value is not known ahead of time."
and that:
"It is used most commonly when coding integers whose upper-bound cannot be determined beforehand."
I don't really understand what is meant by these sentences, because whenever this algorithm is coded, the largest value of the test data or range of the test data would be known before hand. Any help is appreciated!
As far as I'm acquainted with Elias-gamma/delta encoding, the first sentence simply states that these compression methods are global, which means that it does not rely on the input data to generate the code. In other words, these methods do not need to process the input before performing the compression (as local methods do); it compresses the data with a function that does not depend on information from the database.
As for the second sentence, it may be taken as a guarantee that, although there may be some very large integers, the encoding will still perform well (and will represent such values with feasible amount of bytes, i.e., it is a universal method). Notice that, if you knew the biggest integer, some approaches (like minimal hashes) could perform better.
As a last consideration, the same page you referred to also states that:
Gamma coding is used in applications where the largest encoded value is not known ahead of time, or to compress data in which small values are much more frequent than large values.
This may be obtained by generating lists of differences from the original lists of integers, and passing such differences to be compressed instead. For example, in a list of increasing numbers, you could generate:
list: 1 5 29 32 35 36 37
diff: 1 4 24 3 3 1 1
Which will give you many more small numbers, and therefore a greater level of compression, than the first list.
On the project voldemort design page:
http://project-voldemort.com/design.php
It is stated that the hash ring covers the interval [0, 2^31-1].
Now, the interval [0, 2^31-1] represents 2^31 total numbers, and the largest number 2^31-1 is just 31 bits all set to 1. (To convince yourself of this, consider 2^3-1. 2^3=8 and is 0x1000. 2^3-1=7 and is 0x111).
Thus, if a normal 32-bit address word is used to store the value, you have 1 bit free.
Thus, why is 2^31-1 the upper limit? Is that extra bit used for some kind of system bookkeeping?
(e.g. 1 extra bit would provide room for safely adding two valid hash addresses without overflow).
And finally, is this choice specific to voldemort, or is it seen in other consistent hashing schemes?
I think you only have 1 bit free not 2. The -1 accounts for the fact that it starts with the number '0' instead of 1 (the same reason loops count from 0 to count-1). I would guess the reason they use 2^31 instead of 2^32 is that they're using a signed integer so that last bit is the sign bit and so is not useable.
Edit:
From the page you linked:
To visualize the consistent hashing method we can see the possible
integer hash values as a ring beginning with 0 and circling around to
2^31-1.
It specifies an integer so unless you want negative hash values you're stuck with 2^31 instead of 2^32.
Answering a question little late, just by 4 years :)
The reason is Voldemort is written in Java and Java has no unsigned int. 2^31 is already very high for the partitions. Generally we recommend running with only few thousand partitions.
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.