数字
数字
本节首先讨论 Number
类在 java.lang
包中,它的子类,以及您在使用这些类的实例而不是原始数字类型的情况。
本节还介绍了 PrintStream
和 DecimalFormat
类,它们提供用于写入格式化数字输出的方法。
最后,Math
类在 java.lang
中进行了讨论。它包含数学函数来补充语言中内置的运算符。此类具有用于三角函数、指数函数等的方法。
在处理数字时,大多数情况下您在代码中使用基本类型。例如
int i = 500;
float gpa = 3.65f;
byte mask = 0x7f;
但是,有理由使用对象代替基本类型,Java 平台为每个基本数据类型提供了包装类。这些类将基本类型“包装”在对象中。通常,包装由编译器完成——如果您在需要对象的地方使用基本类型,编译器会将基本类型装箱到其包装类中。类似地,如果您在需要基本类型的地方使用数字对象,编译器会为您拆箱对象。有关更多信息,请参阅自动装箱和拆箱部分
所有数字包装类都是抽象类 Number
的子类
注意:还有四个
Number
的子类,这里没有讨论。BigDecimal
和BigInteger
用于高精度计算。AtomicInteger
和AtomicLong
用于多线程应用程序。
您可能使用 Number
对象而不是基本类型有三个原因
- 作为期望对象的函数的参数(通常用于操作数字集合)。
- 使用类定义的常量,例如
MIN_VALUE
和MAX_VALUE
,它们提供数据类型的上限和下限。 - 使用类方法将值转换为其他基本类型,将值转换为字符串,以及在数字系统(十进制、八进制、十六进制、二进制)之间转换。
下表列出了 Number 类所有子类实现的实例方法。
以下方法将此 Number
对象的值转换为返回的基本数据类型。
byte byteValue()
short shortValue()
int intValue()
long longValue()
float floatValue()
double doubleValue()
以下方法将此 Number
对象与参数进行比较。
int compareTo(Byte anotherByte)
int compareTo(Double anotherDouble)
int compareTo(Float anotherFloat)
int compareTo(Integer anotherInteger)
int compareTo(Long anotherLong)
int compareTo(Short anotherShort)
boolean equals(Object obj)
方法 equals(Object obj)
确定此数字对象是否等于参数。如果参数不为 null
并且是相同类型且具有相同数值的对象,则这些方法返回 true
。对于 Double
和 Float
对象,有一些额外的要求,在 Java API 文档中进行了描述。
每个 Number
类都包含其他方法,这些方法对于将数字转换为字符串和从字符串转换为数字以及在数字系统之间转换很有用。下表列出了 Integer
类中的这些方法。其他 Number
子类的方法类似
方法 | 描述 |
---|---|
static Integer decode(String s) |
将字符串解码为整数。可以接受十进制、八进制或十六进制数字的字符串表示形式作为输入。 |
static int parseInt(String s) |
返回一个整数(仅限十进制)。 |
static int parseInt(String s, int radix) |
返回一个整数,给定十进制、二进制、八进制或十六进制(基数分别等于 10、2、8 或 16)数字的字符串表示形式作为输入。 |
String toString() |
返回一个 String 对象,表示此 Integer 的值。 |
static String toString(int i) |
返回一个 String 对象,表示指定的整数。 |
static Integer valueOf(int i) |
返回一个 Integer 对象,保存指定基本类型的值。 |
static Integer valueOf(String s) |
返回一个 Integer 对象,保存指定字符串表示形式的值。 |
static Integer valueOf(String s, int radix) |
返回一个 Integer 对象,保存指定字符串表示形式的整数值,使用 radix 的值进行解析。例如,如果 s = "333" 且 radix = 8,则该方法返回八进制数 333 的十进制整数等效值。 |
格式化数字打印输出
之前您看到了使用 print
和 println
方法将字符串打印到标准输出 System.out
。由于所有数字都可以转换为字符串,因此您可以使用这些方法打印出字符串和数字的任意组合。但是,Java 编程语言还有其他方法,当包含数字时,这些方法允许您对打印输出进行更多控制。
Printf 和 Format 方法
java.io
包包含一个 PrintStream
类,它有两个格式化方法,您可以使用它们来替换 print
和 println
。这些方法,format
和 printf
,彼此等效。您一直在使用的熟悉的 System.out
恰好是一个 PrintStream
对象,因此您可以在 System.out
上调用 PrintStream
方法。因此,您可以在代码中的任何地方使用 format
或 printf
,您之前一直在使用 print
或 println
。例如,
System.out.format(.....);
这两个 java.io.PrintStream
方法的语法相同
public PrintStream format(String format, Object... args)
其中 format
是一个字符串,指定要使用的格式,而 args 是使用该格式打印的变量列表。一个简单的例子是
System.out.format("The value of " + "the float variable is " +
"%f, while the value of the " + "integer variable is %d, " +
"and the string is %s", floatVar, intVar, stringVar);
第一个参数,format
,是一个格式字符串,指定了第二个参数中对象的格式化方式,args
。 format
字符串包含纯文本以及格式说明符,它们是用于格式化 Object...
args 参数的特殊字符。(Object...
args 的表示法称为 *varargs*,这意味着参数的数量可以变化。)
格式说明符以百分号 (%
) 开头,以转换符结尾。转换符是一个字符,表示要格式化的参数类型。在百分号 (%
) 和转换符之间,可以包含可选的标志和说明符。有很多转换符、标志和说明符,它们在 java.util.Formatter
中有详细说明。
以下是一个基本示例
int i = 461012;
System.out.format("The value of i is: %d%n", i)
%d
指定单个变量是十进制整数。%n
是一个与平台无关的换行符。输出结果为
The value of i is: 461012
printf
和 format
方法是重载的。每个方法都有一个具有以下语法的版本
public PrintStream format(Locale l, String format, Object... args)
例如,要以法语系统(在英语表示的浮点数中,使用逗号代替小数点)打印数字,可以使用
System.out.format(Locale.FRANCE,
"The value of the float " + "variable is %f, while the " +
"value of the integer variable " + "is %d, and the string is %s%n",
floatVar, intVar, stringVar);
示例
下表列出了在示例程序 TestFormat.java
中使用的一些转换符和标志,该程序位于表格之后。
转换符 | 标志 | 说明 |
---|---|---|
d | 十进制整数。 | |
f | 浮点数。 | |
n | 适合运行应用程序的平台的换行符。应始终使用 %n ,而不是 \n 。 |
|
tB | 日期和时间转换 - 与语言环境相关的月份全名。 | |
td, te | 日期和时间转换 - 月份中的两位数日期。td 具有必要的首位零,te 没有。 | |
ty, tY | 日期和时间转换 - ty = 两位数年份,tY = 四位数年份。 | |
tl | 日期和时间转换 - 12 小时制中的小时。 | |
tM | 日期和时间转换 - 两位数的分钟,必要时具有首位零。 | |
tp | 日期和时间转换 - 与语言环境相关的上午/下午(小写)。 | |
tm | 日期和时间转换 - 两位数的月份,必要时具有首位零。 | |
tD | 日期和时间转换 - 日期为 %tm%td%ty | |
08 | 宽度为八个字符,必要时具有首位零。 | |
+ | 包含符号,无论是正数还是负数。 | |
, | 包含与语言环境相关的分组字符。 | |
- | 左对齐。 | |
.3 | 小数点后三位。 | |
10.3 | 宽度为十个字符,右对齐,小数点后三位。 |
以下程序展示了可以使用 format 进行的一些格式化操作。输出结果在嵌入式注释中用双引号括起来
import java.util.Calendar;
import java.util.Locale;
public class TestFormat {
public static void main(String[] args) {
long n = 461012;
System.out.format("%d%n", n); // --> "461012"
System.out.format("%08d%n", n); // --> "00461012"
System.out.format("%+8d%n", n); // --> " +461012"
System.out.format("%,8d%n", n); // --> " 461,012"
System.out.format("%+,8d%n%n", n); // --> "+461,012"
double pi = Math.PI;
System.out.format("%f%n", pi); // --> "3.141593"
System.out.format("%.3f%n", pi); // --> "3.142"
System.out.format("%10.3f%n", pi); // --> " 3.142"
System.out.format("%-10.3f%n", pi); // --> "3.142"
System.out.format(Locale.FRANCE,
"%-10.4f%n%n", pi); // --> "3,1416"
Calendar c = Calendar.getInstance();
System.out.format("%tB %te, %tY%n", c, c, c); // --> "May 29, 2006"
System.out.format("%tl:%tM %tp%n", c, c, c); // --> "2:34 am"
System.out.format("%tD%n", c); // --> "05/29/06"
}
}
注意:本节中的讨论仅涵盖
format
和printf
方法的基础知识。更多详细信息可以在本教程的基本 I/O 部分的“格式化”页面中找到。使用String.format()
创建字符串在Strings
中有介绍。
DecimalFormat 类
可以使用 java.text.DecimalFormat
类来控制前导零和尾随零、前缀和后缀、分组(千位)分隔符和小数分隔符的显示。 DecimalFormat
在数字格式化方面提供了很大的灵活性,但它可能会使代码变得更加复杂。
以下示例通过将模式字符串传递给 DecimalFormat
构造函数来创建一个 DecimalFormat
对象 myFormatter
。然后,myFormatter
调用 format
方法(DecimalFormat
从 NumberFormat
继承了该方法) - 它接受一个双精度值作为参数,并以字符串形式返回格式化的数字。
以下是一个示例程序,演示了 DecimalFormat
的用法
import java.text.*;
public class DecimalFormatDemo {
static public void customFormat(String pattern, double value ) {
DecimalFormat myFormatter = new DecimalFormat(pattern);
String output = myFormatter.format(value);
System.out.println(value + " " + pattern + " " + output);
}
static public void main(String[] args) {
customFormat("###,###.###", 123456.789);
customFormat("###.##", 123456.789);
customFormat("000000.000", 123.78);
customFormat("$###,###.###", 12345.67);
}
}
输出结果为
123456.789 ###,###.### 123,456.789
123456.789 ###.## 123456.79
123.78 000000.000 000123.780
12345.67 $###,###.### $12,345.67
下表解释了每行输出结果。
值 | 模式 | 输出结果 | 说明 |
---|---|---|---|
123456.789 | ###,###.### | 123,456.789 | 磅符号 (# ) 表示数字,逗号是分组分隔符的占位符,句点是十进制分隔符的占位符。 |
123456.789 | ###.## | 123456.79 | value 的小数点后有三位数字,但模式只有两位。format 方法通过四舍五入来处理这种情况。 |
123.78 | 000000.000 | 000123.780 | pattern 指定了前导零和尾随零,因为使用了 0 字符而不是磅符号 (#)。 |
12345.67 | $###,###.### | $12,345.67 | pattern 中的第一个字符是美元符号 ($ )。请注意,它紧接在格式化后的 output 中的最左侧数字之前。 |
超越基本算术
Java 编程语言使用其算术运算符支持基本算术运算:+
、-
、*
、/
和 %
。 Math
类位于 java.lang
包中,提供了用于执行更高级数学计算的方法和常量。
Math
类中的所有方法都是静态的,因此可以直接从类中调用它们,例如
Math.cos(angle);
注意:使用静态导入语言功能,您不必在每个数学函数前面写
Math
:import static java.lang.Math.*;
这允许您通过简单名称调用Math
类方法。例如:cos(angle);
常量和基本方法
Math
类包含两个常量
Math
类还包含 40 多个静态方法。下表列出了一些基本方法。
计算绝对值
舍入值
double ceil(double d)
:返回大于或等于参数的最小整数。以double
形式返回。double floor(double d)
:返回小于或等于参数的最大整数。以double
形式返回。double rint(double d)
:返回最接近参数的整数。以double
形式返回。long round(double d)
和int round(float f)
:返回最接近参数的long
或int
,由方法的返回类型指示。
计算最小值
double min(double arg1, double arg2)
float min(float arg1, float arg2)
int min(int arg1, int arg2)
long min(long arg1, long arg2)
计算最大值
double max(double arg1, double arg2)
float max(float arg1, float arg2)
int max(int arg1, int arg2)
long max(long arg1, long arg2)
以下程序 BasicMathDemo
演示了如何使用其中的一些方法
public class BasicMathDemo {
public static void main(String[] args) {
double a = -191.635;
double b = 43.74;
int c = 16, d = 45;
System.out.printf("The absolute value " + "of %.3f is %.3f%n",
a, Math.abs(a));
System.out.printf("The ceiling of " + "%.2f is %.0f%n",
b, Math.ceil(b));
System.out.printf("The floor of " + "%.2f is %.0f%n",
b, Math.floor(b));
System.out.printf("The rint of %.2f " + "is %.0f%n",
b, Math.rint(b));
System.out.printf("The max of %d and " + "%d is %d%n",
c, d, Math.max(c, d));
System.out.printf("The min of of %d " + "and %d is %d%n",
c, d, Math.min(c, d));
}
}
以下是该程序的输出结果
The absolute value of -191.635 is 191.635
The ceiling of 43.74 is 44
The floor of 43.74 is 43
The rint of 43.74 is 44
The max of 16 and 45 is 45
The min of 16 and 45 is 16
指数和对数方法
下表列出了 Math
类的指数和对数方法。
double exp(double d)
:返回自然对数的底 e 的参数次幂。double log(double d)
:返回参数的自然对数。double pow(double base, double exponent)
:返回第一个参数的第二个参数次幂的值。double sqrt(double d)
:返回参数的平方根。
以下程序 ExponentialDemo
显示了 e
的值,然后对任意选择的数字调用上表中列出的每个方法
public class ExponentialDemo {
public static void main(String[] args) {
double x = 11.635;
double y = 2.76;
System.out.printf("The value of " + "e is %.4f%n",
Math.E);
System.out.printf("exp(%.3f) " + "is %.3f%n",
x, Math.exp(x));
System.out.printf("log(%.3f) is " + "%.3f%n",
x, Math.log(x));
System.out.printf("pow(%.3f, %.3f) " + "is %.3f%n",
x, y, Math.pow(x, y));
System.out.printf("sqrt(%.3f) is " + "%.3f%n",
x, Math.sqrt(x));
}
}
以下是运行 ExponentialDemo
时将看到的输出结果
The value of e is 2.7183
exp(11.635) is 112983.831
log(11.635) is 2.454
pow(11.635, 2.760) is 874.008
sqrt(11.635) is 3.411
三角函数方法
Math
类还提供了一组三角函数,在下表中进行了总结。传递给每个方法的值是以弧度表示的角度。可以使用 toRadians(double d)
方法将度数转换为弧度。
double sin(double d)
:返回指定双精度值的正弦。double cos(double d)
:返回指定双精度值的余弦。double tan(double d)
:返回指定双精度值的正切。double asin(double d)
:返回指定双精度值的反正弦。double acos(double d)
:返回指定双精度值的反余弦。double atan(double d)
:返回指定双精度值的反正切。double atan2(double y, double x)
: 将直角坐标 (x, y) 转换为极坐标 (r, theta) 并返回 theta。double toDegrees(double d)
和double toRadians(double d)
: 将参数转换为度数或弧度。
以下是一个名为 TrigonometricDemo
的程序,它使用这些方法中的每一个来计算 45 度角的各种三角函数值。
public class TrigonometricDemo {
public static void main(String[] args) {
double degrees = 45.0;
double radians = Math.toRadians(degrees);
System.out.format("The value of pi " + "is %.4f%n",
Math.PI);
System.out.format("The sine of %.1f " + "degrees is %.4f%n",
degrees, Math.sin(radians));
System.out.format("The cosine of %.1f " + "degrees is %.4f%n",
degrees, Math.cos(radians));
System.out.format("The tangent of %.1f " + "degrees is %.4f%n",
degrees, Math.tan(radians));
System.out.format("The arcsine of %.4f " + "is %.4f degrees %n",
Math.sin(radians),
Math.toDegrees(Math.asin(Math.sin(radians))));
System.out.format("The arccosine of %.4f " + "is %.4f degrees %n",
Math.cos(radians),
Math.toDegrees(Math.acos(Math.cos(radians))));
System.out.format("The arctangent of %.4f " + "is %.4f degrees %n",
Math.tan(radians),
Math.toDegrees(Math.atan(Math.tan(radians))));
}
}
该程序的输出如下所示。
The value of pi is 3.1416
The sine of 45.0 degrees is 0.7071
The cosine of 45.0 degrees is 0.7071
The tangent of 45.0 degrees is 1.0000
The arcsine of 0.7071 is 45.0000 degrees
The arccosine of 0.7071 is 45.0000 degrees
The arctangent of 1.0000 is 45.0000 degrees
随机数
random()
方法返回一个介于 0.0 和 1.0 之间的伪随机数。范围包括 0.0 但不包括 1.0。换句话说:0.0 <= Math.random() < 1.0
。要获得不同范围内的数字,可以对 random
方法返回的值进行算术运算。例如,要生成一个介于 0 和 9 之间的整数,可以这样写:
int number = (int)(Math.random() * 10);
通过将值乘以 10,可能的取值范围变为 0.0 <= number < 10.0
。
当需要生成单个随机数时,使用 Math.random
非常有效。如果需要生成一系列随机数,则应创建一个 java.util.Random
实例,并调用该对象上的方法来生成数字。
上次更新: 2021 年 9 月 14 日