Watch this space for updates!
At the end of last week's accelerated exercise, we were pondering the following question:
What are the ways your program can be modified to handle larger numbers - say, of 100 to 1000 digits ?
In this week's exercise, we will look into two salient aspects of handling big integers.
First, how might we go about storing a number that has thousands of digits?
Second, how would we want to manipulate such a number; what sorts of operations
would we want our big-integer type MyBigInteger
to support? If we're going to have two
different mutable-integer data types,
MyInteger
and MyBigInteger
, will we be doomed to write two
different implementations of every algorithm that works on integers? In particular, must we write a
getFactor(MyBigInteger)
method, duplicating the work we
previously did on getFactor(MyInteger)
?
<source files: MyBigInteger.java MyInteger.java>
We'll see how one might deal with these two aspects of large numbers as the exercise progresses. [Please note, however, that the approach that you're asked to follow below is only one of many possibilities---as you proceed through the exercise, you are strongly encouraged to ask yourself what the alternatives and the trade-offs are.]
Take a look at the MyNumber
and MyIntegralNumber
interfaces, which
are intended to abstract the signature of MyInteger
.
< source files: MyNumber.java
MyIntegralNumber.java
>
What are the advantages of making MyIntegralNumber
an interface
instead of an abstract class? What are the disadvantages? (You
may want to revisit this question after you complete the rest of
the exercise...)
Once you're familiar with those two interfaces, bring your MyInteger
code from HW #1 under their umbrella, by modifying
MyInteger
so that it correctly implements the MyIntegralNumber
interface.
[You may use the HW #1 sample solution's MyInteger
code instead of
your own MyInteger
code, if you prefer to do so.]
Complete the MyNumbers
class, as a quick
warm-up exercise in dealing with numbers via an interface.
< stub file: MyNumbers.java
>
Widen the applicability of your Factorize
code from HW #1, by modifying
getFactor
so that it takes a MyIntegralNumber
instead of a
MyInteger
.
class Factorize { public static void getFactor(MyIntegralNumber ival) { ... } }
(Of course, there's a bit more to this step than simply changing the method header.)
[You may use the HW #1 sample solution's Factorize
code instead of your
own Factorize
code, if you prefer to do so.]
<source file: Factorize.java>
What are some of the advantages of using MyIntegralNumber
instead of the
more concrete type MyInteger
? What are some of the disadvantages? Please
take a moment to consider how the concepts of abstraction, polymorphism, and
modularity might be at work in this case.
Try out your refurbished factorization code by encapsulating the numbers 169, 899, 401,
769, and 68983 in MyInteger
objects and passing them to getFactor.
Implement the MyBigInteger
class.
[Your big-integer code should all be written "from scratch"; you may not rely on
java.math.BigInteger
, java.math.BigDecimal
, or any other "big number"
code that you do not write yourself. (You may, however, use utility
classes such as java.util.Vector
and java.util.List
, if you wish.) The
idea is for you to learn the details of how big-integer data structures
work, by implementing the internals of (a simplified) one yourself.]
< stub file: MyBigInteger.java
>
Try out your MyBigInteger
code by encapsulating the numbers
169, 899, 401, 769, and 68983
in MyBigInteger
objects and passing them
to getFactor
.
Once you've convinced yourself that things are working smoothly, try finding a non-trivial factor of the "slightly larger" integer 100132; written explicitly (in decimal) this number is...
1032500996162285568402413441490620685601924366584503199521929020299321666762393411964960496032001
(Your code should be able to find a non-trivial factor of the above integer, in a reasonable amount of time.)
Why keep MyInteger
around? Isn't it redundant, now that we have
MyBigInteger
?
Realistically, how many digits can your implementation of getFactor
handle? Would factoring a 1000-digit number be feasible? Are some 1000-digit numbers
easier to factor than others?
If you're confident in the efficiency of your code, you might be interested in trying more challenging input, such as...
(These five test-cases are optional.)
Try out any other big-integer examples that pique your interest, and have fun!
You'll need to submit the following items:
MyInteger
MyNumbers
Factorize
MyBigInteger
MyInteger
-based factorization test runs [from step five]
MyBigInteger
-based factorization test runs [from step seven]MyInteger.java
MyNumbers.java
Factorize.java
MyBigInteger.java
*.java
files that your wrote...
v.txt
[output from step five]
vii.txt
[output from step seven]
*.txt
output files...
MyNumber.java
MyIntegralNumber.java
Please recall that, in general, your electronic submission must include all of the source files required to compile your program(s) but that your hardcopy submission should, in contrast, only include the source files that you wrote (or modified).
Looking for hints? Please see the new hints page.
Note 1: | You needn't worry too much about efficiency in this exercise. At this point in the course, we're more interested in correctness, structure, style, and design. Please feel free to use straightforward / naïve algorithms, as long as the test factorizations specified above (and similar cases) take less than an hour or two to run. |
Note 2: | You do not need to hand in answers to the questions posed above. We just want you to get into the habit of thinking critically about design decisions (yours as well as other peoples'). For this exercise, you only need to hand in Java code and test-run output. |
Note 3: |
|
Note 4: | In general, your implementations must comply with the comments and documentation
given in the supplied stub files (
You may add members, fields, superclasses, etc. to You may define as many additional classes and interfaces as you see fit. |
Note 5: | You must not modify the definitions of the two mutable-number interfaces, (In particular, you may not add methods or The idea is to work within the constraints imposed by those two interfaces (and to learn something about the costs and benefits of abstraction as you go). |
Note 6: |
"A non-trivial factor of So, the non-trivial factors of |