|
WELCOME to the Core Java Technologies Tech Tips (formerly the Java Developer Connection (JDC) Tech Tips), August 6, 2002. Here you'll get tips on using core Java technologies and APIs, such as those in Java 2 Platform, Standard Edition (J2SE). This issue covers: These tips were developed using Java 2 SDK, Standard Edition, v 1.4. This issue of the Core Java Technologies Tech Tips is written by Glen McCluskey. Generating Prime NumbersA prime number is an integer greater than 1, with only itself and 1 as divisors. The first few primes are 2, 3, 5, 7, 11, and 13.
This tip examines two ways of generating primes. The first approach works for relatively small (32-bit) prime numbers. The second uses the Here's an example of where prime numbers are used. Suppose that you're working on a custom hash table scheme. You know that there will be about 1000 entries in the table, and you want the table to be no more than two thirds full, relative to the number of slots available. This implies a table size of 1500. A common hash table algorithm uses a table size that's prime, in order to reduce the number of collisions. So you need to find a prime number with a value near 1500. How can you do this? Here's one way:
The The output of the program is:
1511
that is, 1511 is the smallest prime of value 1500 or above. This approach does the job, and is reasonably fast. But it has a couple of shortcomings. One problem is that you can't use the program to generate prime numbers above 32 bits (about 10 decimal digits). (To convert a number of bits to an approximate number of decimal digits, multiply by log10(2), or 0.301). Some applications require very long primes, such as 2048 bits (approximately 615 digits). An example is encryption, which relies on the idea that the product of two large primes cannot readily be factored into those primes -- except by a brute-force attack using very large amounts of computer time.
Even if the There is indeed a very fast way to generate large primes, but with a catch. The generated numbers are probably prime, but there is a slight chance that they might not be. The standard set by ANSI X9.80 specifies a certainty for use in private-key encryption: the probability that a generated prime is actually prime is greater than 1 minus 1/2 to the 100th power. So there's less than a 1 in 2 to the 100th power chance that a generated number is not prime. 1 in 2 to the 100th power is about 1 in 1.27 times 10 to the 30th power, which is indeed a very low probability. Given this background, how do you actually generate a big prime? Here's a simple example:
This program generates a 100-bit prime, using the passed-in
689572171629632424814677540353
The
How fast does
When you run the program, you should get results like this (your results might differ depending on your operating environment):
ms to generate 100 bit prime = 31
ms to generate 200 bit prime = 111
ms to generate 300 bit prime = 235
These results show that it took 31 milliseconds to generate a 100-bit prime, 111 milliseconds to generate a 200-bit prime, and 235 milliseconds to generate a 300-bit prime. Clearly, the time it takes to generate primes is not linear in relation to the number of bits.
There are a number of other prime-related features in For more information about generating prime numbers, see section 4.5.4, "Factoring Into Primes", and section 6.4, "Hashing" in "The Art of Computer Programming" by Donald Knuth. Also, see "Enhancements to java.math". When Not to Overload Methods
Suppose that you are writing a Java application, and you have some code like this that uses overloading for
What happens when this code is executed? First,
Next,
Actually, this analysis is wrong in both cases. When you run the
methodA(int) called
methodB(float) called
The point of this tip is not to discuss the intricacies of overloading, but simply to present the idea that most Java programmers don't fully understand how overloading works. It's smart to write your code so that they don't have to worry about these intricacies. This tip presents several ways to write code that avoids overloading issues. But first, let's look at one more example that illustrates how method overloading can be confusing:
The
classify as A
B.f called
The
This example illustrates a major source of confusion with method overloading, a confusion that stems from the difference between overloading and overriding. The choice of which overloaded method to call is made by the compiler. In the
How do you avoid problems with overloading? One approach is to not overload at all. Instead, give methods different names, corresponding to the types of their parameters. For example, the
There is no overloading in this code, so which methods are called is very clear. A similar technique is used in some of the standard library classes such as Another approach to eliminating confusion with overloading is to specify a different number of parameters for each of a set of overloaded methods. Alternatively, make sure that the parameter types are radically different from each other. Let's look at a final example to see how this works:
In this example, the The first and second constructors have different numbers of parameters, so it's easy to tell them apart. The first and third constructors both have a single parameter, but in one case it's a String, and in the other case an int, so it's easy to distinguish these.
Note that even with
MyDate d = new MyDate(10, 12, 1959);
might be interpreted two different ways by someone who reads the code. The interpretation depends on whether the person reading the code is accustomed to specifying the month number before or after the day number. What date is being referred to here, October 12 or December 10? It's possible that additional work needs to be done to make this class easier to use. An enumerated type could be used to specify the month. Static factory methods could be used for creating dates. Unlike for constructors, you can give static factory methods distinct names that describe their function. Some examples of parameter types not radically different from each other include:
Overloading is a useful technique, but it pays to be cautious. You don't want to end up with code that's impossible to read, or that takes advantage of arcane rules that few programmers understand. It should be possible for an average reader to look at your code and know exactly what method is being called at any point. For more information about alternatives to overloading methods, see item 1 "Consider providing static factory methods instead of constructors" and item 26 "Use overloading judiciously" in "Effective Java Programming Language Guide" by Joshua Bloch; and Section 5.3 "Method Invocation Conversion" and Section 15.12.2 "Compile-Time Step 2: Determine Method Signature" in "The Java Language Specification Second Edition" by Gosling, Joy, Steele, and Bracha.
IMPORTANT: Please read our Terms of Use and Privacy policies:
FEEDBACK
SUBSCRIBE/UNSUBSCRIBE
- ARCHIVES
- COPYRIGHT
This document is protected by copyright. For more information, see:
Core Java Technologies Tech Tips Sun, Sun Microsystems, Java, Java Developer Connection, J2SE, J2EE, and J2ME are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. | |||||||||||||
Oracle is reviewing the Sun product roadmap and will provide guidance to customers in accordance with Oracle's standard product communication policies. Any resulting features and timing of release of such features as determined by Oracle's review of roadmaps, are at the sole discretion of Oracle. All product roadmap information, whether communicated by Sun Microsystems or by Oracle, does not represent a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. It is intended for information purposes only, and may not be incorporated into any contract.
|
| ||||||||||||