| Thinking in Java, 2nd edition -8 |
|
|
Sunday, 07 May 2006 | Bruce Eckel для раздела Ученье – свет Детали расчетаИнструкция char c = (char)(Math.random() * 26 + 'a'); заслуживает более подробного рассмотрения. Math.random( ) производит double, так что значение 26 переводится в double для выполнения умножения, которое также производит double. Это означает, что ‘a’ должно переводится в double для выполнения сложения. Результат типа double переводится назад к char с помощью приведения.
Что делает приведение к char? То есть, если вы имеете значение 29.7 и вы приводите его к char, будет ли результирующее значение равно 30 или 29? Ответ можно найти в этом примере:
//: c03:CastingNumbers.java
// Что случается, когда вы приводите float
// или double к целому значению?
public class CastingNumbers {
public static void main(String[] args) {
double
above = 0.7,
below = 0.4;
System.out.println("above: " + above);
System.out.println("below: " + below);
System.out.println(
"(int)above: " + (int)above);
System.out.println(
"(int)below: " + (int)below);
System.out.println(
"(char)('a' + above): " +
(char)('a' + above));
System.out.println(
"(char)('a' + below): " +
(char)('a' + below));
}
} ///:~
Вот результат:
above: 0.7
below: 0.4
(int)above: 0
(int)below: 0
(char)('a' + above): a
(char)('a' + below): a
Так что ответ такой: приведение float или double к целому значению происходит простым обрезанием.
Второй вопрос относительно Math.random( ). Тут производится значение от нуля до одного, включая или не включая значение ‘1’? На математическом языке: (0,1) или [0,1], или (0,1] или [0,1)? (Прямоугольная скобка означает “включая”, а круглая скобка означает “не включая”.)
И в этот раз тестовая программа поможет получить ответ:
//: c03:RandomBounds.java
// Может ли Math.random() производить 0.0 и 1.0?
public class RandomBounds {
static void usage() {
System.out.println("Usage: nt" +
"RandomBounds lowernt" +
"RandomBounds upper");
System.exit(1);
}
public static void main(String[] args) {
if(args.length != 1) usage();
if(args[0].equals("lower")) {
while(Math.random() != 0.0)
; // Продолжаем пробовать
System.out.println("Produced 0.0!");
}
else if(args[0].equals("upper")) {
while(Math.random() != 1.0)
; // Продолжаем пробовать
System.out.println("Produced 1.0!");
}
else
usage();
}
} ///:~
В обоих случаях вы можете прервать программу в ручную в том случае, если окажется, что Math.random( ) никогда не производит 0.0 или 1.0. Но такой экспериметн может обмануть. Если вы узнаете, что есть примерно 262 различных значений типа double в пределах от 0 до 1, вероятность достижения любого единичного значения экспериментально может превышать время жизни компьютера и даже экспериментатора. Считается, что 0.0 - включается в выходные значения Math.random( ). или, на математическом языке, [0,1].
|