|
home—info—exams—lectures—labs—hws
Recipe—Laws—lies—syntax—java.lang docs—java.util docs
(double) 5 int m = 13; int n = 5; ((double) m) / ((double) n) |
Web traffic is sent on postcards. How to securely communicate your credit-card number to amazon, without any pre-arrangement? “Inconceivable!”?
Amazon might say on their web page:
Our public key pubKey = 37. If you want to send us a secret message privMsg (a two-digit number), multiply your secret number by our public key, and tell us the last two digits (only) of the result: That is, tell us (privMsg * pubKey) % 100. (We can name this result pubMsg.)Is announcing pubMsg secure, even if there are eavesdroppers? Let's try it! A volunteer: Choose your secret privMsg and write it down, without telling anybody. Compute pubMsg, and announce it. Can any of you eavesdroppers figure out the original message? (You want to just divide by 37, but how to do that in this world of mod-100 arithemetic?) The original privMsg was …
Note that this used no pre-arrangement between the sender and the receiver. This is called “public key cryptography”, since eavesdroppers know as much about breaking the code as the sender.
You could break this code, if you could divide by 37 mod 100. (Or more precisely: find the multiplicative inverse of 37, mod 100.) Project: read about the extended Euclidean algorithm for calculating muliplicative inverses. Break this code!
Although this particular scheme is easy to break with a bit of math knowledge (this Extended Euclidean algorithm), the example is to motivate how a public-key system is even conceivable.
We also have the issue of overflow with doubles. Try 1e308 + 1e308. Double.MAX_VALUE. (Keep in mind that 10308 is a ridiculously huge number; there are “only” 1080 particles in the universe (electrons, photons, quarks...), 1090 is a ten billion times bigger. So 10308 is a number that doesn't correspond to any reasonable physical amount.
There is another twist to this: we might try to compute numbers which are so close to 0 they can't be represented by a double: Double.MIN_VALUE. Try Double.MIN_VALUE/2. As before, we have a trade-off between float vs double.
Aside: Java does have a way to do exact arithmetic, but it takes some extra typing:(This is a teaser to next week, when we'll talk about state, constructor-methods, and calling constructors with new.)
java.math.BigInteger ratherLarge1 = new java.math.BigInteger( "987654321098765432109876543210" ); java.math.BigInteger ratherLarge2 = new java.math.BigInteger( "012345678901234567890123456789" ); (ratherLarge1.add(ratherLarge2)).toString();
We mentioned, that casting raises the specter of silent overflow issues: If casting an int to a double, you are throwing away accuracy. But worse, if you cast a large double to an int, and that double is bigger than Integer.MAX_INT, the cast will silently succeed, with a wildly incorrect value!
(int) 7e35 // Size of the universe, in nanometers... whereas 2billion nanometers ~ 6ft. |
Edict of Programming: When possible, using int is preferred to double. For instance, the price of an item is often best given in integer cents, rather than double dollars. This will avoid accumulation of small errors, as in 2.00-1.10 vs. 200-110.(We won't enforce this in grading for this class though.)
Write the following function:
/** Return a nicely formatted String representing a price in dollars. * @param cents An amount of money (in cents). * @return A String representing cents, in dollars. * Examples: * dollarAmount(167) = "$1.67" * dollarAmount(43) = "$0.43" * dollarAmount(__) = ______ */ String dollarAmount( int cents ) { ________________ } |
Note that really, we're relying on the fact that when Java sees + with a String on one side and an int on the other, then it is calling (behind our back) an int-to-String conversion function.
Beware numerical inaccuracies: (2.0 - 1.1 == 0.9), or ( (7.0/25.0)*25.0 == 7.0 ).
double x = 2.0 - 1.1; double y = 0.9; x == y // huh? That's an unexpected answer. How to debug? x // Oh, now it's clear what happened. |
Edict of Programming: Do not use == with doubles.So how do we see if two doubles are practically-equal? One immediate imponderable is “how close is close enough to be considered practically equal”? Well, for the moment2, let's say being within 0.001 is close enough: ((y-0.001 < x) && (x < y+0.001)) is a start. This amount 0.001 is often called the “tolerance” of the comparison.
Actually, we should look at an relative difference between two terms, rather than an absolute difference.
We have covered many topics over the last 3.5 weeks:
1 This is a preview: Just as there are built-in classes String and Math, there is also a class named Integer. The class Integer is a “wrapper class” for its little cousin, type int. We won't go into details, but just keep in mind that while int and class Integer are related, the primitive type int is not a class. ↩
2We'll later realize that we really should compare the relative size of the two numbers: 0.001 might be good for comparing people's height in inches, but not for the width of two hairs in inches. ↩
home—info—exams—lectures—labs—hws
Recipe—Laws—lies—syntax—java.lang docs—java.util docs
©2007, Ian Barland, Radford University Last modified 2007.Aug.27 (Mon) |
Please mail any suggestions (incl. typos, broken links) to ibarlandradford.edu |