how would one multiplies two big integers in LISP - lisp

Given an n-place integer and an m-place integer. How can I multiply them in LISP using lists, arrays or any other lisp specific data types?
for instance;
a(1)a(2)...a(n)
b(1)b(2)...b(m)
with result of;
r(1)r(2)...r(m+n)

Common Lisp has already bignums natively. Why don't you use them?
You basically don't have to declare anything specially, they "magically" happen:
% sbcl
This is SBCL 1.0.56.0.debian, an implementation of ANSI Common Lisp.
* (defun fact (n) (if (< n 1) 1 (* n (fact (- n 1)))))
FACT
* (fact 50)
30414093201713378043612608166064768844377641568960512000000000000
So with a Common Lisp, you basically don't have to bother...
addenda
And efficient bignum algorithms are a very difficult problem; Efficient algorithms have better complexity than naive ones; you can find difficult books explaining them (the underlying math is pretty hard). See also this answer.
If you want to make a competitive bignum implementation, be prepared to work hard several years, and make it a PhD thesis.

A simple algorithm to use is just mimicking what you do when computing mutiplications by hand:
123 x
456 =
---
738
615
492
-----
56088
The first step is implementing multiplication by a single "digit" (e.g. 123 x 6 = 738).
After you have that shifting is of course trivial (just slide elements in your list) and therefore multiplication can then be completed using your addition function.
Note that this is not the fastest way to compute the product of two big numbers (see Karatsuba algorithm for example).
PS: thinking to how you can compute the product of two large numbers by hand also explains some "amazing" result like 111111111*111111111 = 12345678987654321
111111111 x
111111111 =
---------
111111111
111111111
111111111
111111111
111111111
111111111
111111111
111111111
111111111
-----------------
12345678987654321

(* 1234567890123456789123456789 1234567890123456789123456789)
Big ints are native to Common Lisp.

Related

Inaccuracy in number->string in Scheme

I am working on a Scheme program, where I need at some place a pair of a floatingpoint counter and the same counter as formated string. I am having issues with the number to string conversion.
Can someone explain me these inaccuracies in this code ?
(letrec ((ground-loop (lambda (times count step)
(if (= times 250)
(begin
(display "exit")
(newline)
)
(begin
(display (* times step)) (newline)
(display (number->string (* times step)))(newline)
(newline)
(newline)
(ground-loop (+ times 1) (* times step) step)
)
)
)
))
(ground-loop 0 0 0.05)
)
Part of the output looks like that
7.25
7.25
7.3
7.300000000000001
7.35
7.350000000000001
7.4
7.4
7.45
7.45
7.5
7.5
7.55
7.550000000000001
7.6
7.600000000000001
7.65
7.65
I am aware of floating point inaccuracies and tried several forms of increasing the counter but the issue is in the conversion itself.
Any ideas for an easy fix? Tried a bit with explicitly rounded numbers but this did not do the job. The results even vary from IDE and environment to environment. Do I really have to do string manipulation after conversion?
The very weird thing in my case is having an exact numeric result but the string is off.
Thank you
It looks to me as if:
the native float type (the type you get by reading 1.0) of your implementation is IEEE double float;
the display of your Scheme is not printing such floats 'correctly' (see below, I'm no sure this means it's buggy);
your number->string is doing the right thing.
By 'correctly' above I mean 'in a way so that reading what display printed returns an equivalent number'. I am not at all sure that display is required to be correct in this restrictive sense however, so I am not sure whether it's a bug. Someone who understands the Scheme standards better than I do might be able to comment on that.
In particular if the native float type of the languageis an IEEE double float, then, for instance:
(= (* 0.05 3) 0.15)
is false, as is
(= (* 0.05 146) 7.3)
Which is the example you have in the first line of your output.
So you certainly should not assume that your program will ever produce a number equal to the number you get by reading 7.3 for instance, because it won't.
In the above I have carefully avoided printing the numbers out, and that's because I'm not sure display is reliable on this, and in particular I'm not sure your display is reliable or that it is required to be.
Well, I have a Lisp implementation to hand which is reliable about this. In this system the default float format is a single-precision IEEE float, and I can get the reader to read double floats with, for instance 1.0d0. So, in this implementation you can see the results:
> (* 0.05d0 3)
0.15000000000000002D0
> (* 0.05d0 146)
7.300000000000001D0
And you'll see that these are exactly (up to the double-precision indicator) what number->string is giving you and not what display is giving you.
If what you want to do is to get a representation of the number in such a way that reading it will return an equivalent number, then number->string is what you should trust. In particular R5RS says in section 6.2.6 that:
(let ((number number)
(radix radix))
(eqv? number
(string->number (number->string number
radix)
radix)))
is true, and 'it is an error if no possible result makes this expression true'.
You can check the behaviour of number->float & float->number over a range of numbers by, for instance (this may assume a more recent or featurefull Scheme than you have):
(define (verify-float-conversion base times)
(define (good? f)
(eqv? (string->number (number->string f)) f))
(let loop ([i 0]
[bads '()])
(let ([c (* base i)])
(if (>= i times)
(values (null? bads) (reverse bads))
(loop (+ i 1) (if (good? c) bads (cons c bads)))))))
Then you should get
> (verify-float-conversion 0.05 10000)
#t
()
More generally using floats, still more floats that are the result of some computation more complicated than reading them some input source, as unique indices into any kind of tabular structure is fraught with danger to put it rather mildly: floating-point errors mean that it's just really dangerous to assume that (= a b) is true for floats even when it mathematically should be.
If you want such indices do exact arithmetic instead, and convert the results of that arithmetic to floats at the point you need to do computations. I believe (but am not sure) that Scheme implementations are nowadays required to support exact rational arithmetic (certainly this seems to be true for R6RS), so if you want to count 20ths (say) you can do so by counting in units of 1/20, which is exact, and then constructing floats when you need them.
It's probably safe to compare floats in the case that if you are for instance comparing a float you got by taking some initial float value and multiplying it by a machine integer and comparing it with some earlier version of itself which you have read by string->number. But if the calculation your doing is more complicated than that you need to be quite careful.

RSA Prime Generation using Provable vs Probable Prime Construction

I am trying to implement RSA prime generation for P and Q based on FIP186-4 specification. The specification describes two different implementations: Section 3.2 Provable Prime Construction vs. Section 3.3 Probable Prime Construction. Initially, I tried implementing the probable prime approach because it is easier to understand and implement, but I discovered it is very slow because of the number of iterations needed to find P and Q primes (worst case it takes 15 minutes). Next, I decided to try the provable prime approach but I found out the algorithm is much more complex and might be slow as well. Below are my two issues:
In Section C.10, Step 12, how to eliminate the sqrt(2) to the expression x = floor(sqrt(2))(2^(Lāˆ’1))) + (x mod (2^L āˆ’ floor((sqrt(2)(2^(Lāˆ’1))))) so that I can represent it as whole numbers using BigNum representation?
In Section C.10, Step 14, is there a fast way to compute y in the interval [1, p2] such that 0 = ( y p0 p1ā€“1) mod p2? The specification doesn't specify a method to implement this. My initial thought was to perform a linear search staring from integer 1 and up but that can be very slow because p2 can be a very large number.
I tried searching online for help on this issue, but I discovered a lot of examples don't even comply with FIPS186-4. I assume it is because these two methods are too slow.

coerce function in common lisp -- arrays and lists

I am seeing different behavior of coerce between different versions of Common Lisp - wondering which one is "right" or is the standard ambiguous on this seemingly simple question:
is
(coerce '(1 2 3) 'array)
correct lisp? It works fine in Clozure Common Lisp but not in sbcl.
And when it does not work what is the easiest way to coerce a list into an array?
Thanks
The specification says:
If the result-type is a recognizable subtype of vector, and the object is a sequence, then the result is a vector that has the same elements as object.
array is not a subtype of vector -- vectors are 1-dimensional arrays, but array includes arrays with any number of dimensions.
You can use one of these
(coerce '(1 2 3) 'vector)
(coerce '(1 2 3) '(array t (*)))
In the second version, (*) specifies a single dimension whose size is unspecified.
Your use is unspecified, so implementations are free to implement it as they please. If it returns a value, the value has to be an ARRAY of some kind.
To add to Barmar's answer (this is really a comment, but it's too long), while it's fine for CCL to do what it does, I think it's clear that something like this would be very hard to define in a standard.
Consider something like this:
(coerce '((1 2 3) (4 5 6) (7 8 9)) 'array)
What is the result of this meant to be? Should it be:
a vector each of whose elements is a three-element list?
the equivalent of (make-array '(3 3) :initial-contents '((1 2 3) (4 5 6) (7 8 9)))?
the transpose of that array?
I think either of the first two are reasonable interpretations: sometimes you will want one, sometimes the other. The third is probably not reasonable given CL is a row-major language.
So if (coerce ... 'array) were in the standard, how would you specify which of these you wanted? If you just chose one, which should it be (and how do you now reach agreement with the people on the committee who think it should be the other!)?

Modular arithmetic Basic cofusion

I am just learning number theory .When I was reading modular arithmetic I came across this statement :
29 is congruent to 15 (mod 7).
So actually this statement actually shows just
29 is congruent to 15
and we are working under mod 7..mod 7 in brackets is just to show the modulus. It is not 29 is congruent to 15%7.It is 29 is congruent to 15 and we are working under modulus 7.
Your observation is correct. The word mod is actually used in two different senses: one of them is to clarify a relation as you describe
A = B (mod C)
means, e.g., that B-A is divisible by C. Or sometimes (but equivalently in the end), it means that you should be reading A and B as being notation, e.g., for elements of the algebraic structure integers modulo C rather than as notation for integers.
The other usage is as a binary operator: B mod C means the remainder when B is divided by C.
Usually it's straightforward to tell the difference from context... assuming you are actually aware of both possible usages. Also, in the first kind of usage, mod is usually set off from the others; e.g.
A = B mod C
is the first usage as a relation, but
A = B mod C
could go either way.

How to display rationals as long lists of digits in Lisp?

I'm just starting to learn Lisp and was wondering how to display a rational as a decimal number with lots of digits.
If I use (float x), where x is a rational then it displays about 8 digits or so. But I want to display hundreds of digits.
You will have to implement an algorithm to basically do the long division and calculate the digits yourself. There is no native datatype capable of holding hundreds of decimal digits.
You can use CLISP, an implementation of Common Lisp. As an extension it provides floats with settable precision. See: http://clisp.cons.org/beta/impnotes/num-concepts.html#lfd
There are also systems like Maxima and Axiom that run on top of Common Lisp. These also can compute with high precision reals.
The Common Lisp standard though doesn't provide that.
There may be implementations on which (format nil "~,100F" x) does what you want. But on most this first converts to a float, then computes digits, which loses precision.
It's not too hard to program your own. The idea is to compute the parts before and after the decimal point as integers separately. Here's my proposal:
(defun number->string-with-fixed-decimal-places (x width &optional stream)
"Print an approximation of <x> with <width> digits after the decimal point."
(multiple-value-bind (int dec) (truncate x)
(let ((dec-shifted (truncate (* (abs dec) (expt 10 width)))))
(format stream "~d.~v,vd" int width #\0 dec-shifted))))