CodeGym /课程 /JAVA 25 SELF /小数与 double 类型入门

小数与 double 类型入门

JAVA 25 SELF
第 6 级, 课程 2
可用

1. 小数

假设你决定编写一个最简单的计算器,或者任何需要进行计算的程序(从最基本的金额统计到复杂的物理计算)。现实生活中并不是所有东西都是整数——这点无可奈何!

所以,让我们掌握一种新的数据类型吧!

在编程中,小数也被称为实数,或浮点数floating-point)。在 Java 中,与大多数语言一样,它们用于存储不仅是整数,还有各种“带小数”的值:例如 3.14-28.572.718281828……

浮点数主要有两种类型:

类型 存储 值范围(近似) 精度 典型大小
float
数字 ±1.5 × 10-45 ... ±3.4 × 1038 小数点后约 7 位 4 字节
double
数字 ±5.0 × 10-324 ... ±1.7 × 10308 小数点后约 15–16 位 8 字节

float 类型

float 这个名称源自 floating-point number——浮点数。数学中的“实数”有其严格的性质,而计算机有很多限制。因此在 Java 中把小数称为实数并不十分准确,通常称为“浮点数”。

float 通常可保存 7 位有效数字(例如 0.1234567)、一个 10 的指数,并占用 4 字节内存。对于精确计算来说这太少了,因此大家很快就转向了双精度。

double 类型

double 之名来源于双精度(double)。它在内存中占用 8 字节(是 float 的 2 倍),可保存最多约 15 位有效数字:0.123456789012345。对于大多数涉及小数的计算,这已经足够,因此 double 是 Java 中存储小数的首选类型。

本讲将重点介绍 double:默认情况下,所有“常见”的小数都建议使用它。当然,我们后面也会提到 float

2. 声明并初始化 double 类型变量

一切都与 int 类似——只是现在使用 double

// 声明变量并赋值为圆周率
double pi = 3.1415926;

// 也可以只声明而不初始化
double averageSalary;
averageSalary = 91234.56;

// 可以进行运算!
double pizzaPieces = 8;
double friends = 3;
double piecesPerFriend = pizzaPieces / friends; // 2.666...(而不是 2)

语法要点:

  • 小数点分隔符使用 点号3.14)。如果使用逗号——会导致编译错误!
  • 严格来说,写成 double d = 3; 并不会报错——类型会自动转换(整数无损地变成“浮点数”)。

3. 使用 Scanner 输入和输出小数

先来尝试输出一个小数:

double amount = 42.75;
System.out.println(amount); // 输出:42.75

很好!如果再加上一些文本:

System.out.println("您的账户余额:" + amount + " 欧元。"); // 您的账户余额:42.75 欧元。

从键盘输入

要读取 double,需要使用 Scanner 的专用方法:console.nextDouble()

Scanner console = new Scanner(System.in);

System.out.println("请输入室外温度:");
double temperature = console.nextDouble(); // 直接读取为 double

System.out.println("现在室外:" + temperature + " 度。");

4. double 实战:算术运算

所有常见运算(+-*/)与 int 一样工作:

double distance = 100.5;
double time = 2.0;
double speed = distance / time; // 50.25

System.out.println("平均速度:" + speed); // 平均速度:50.25

这就是全部的算术了。唯一的不同在于:只要任一操作数是 double,除法的结果就一定是小数。

int 比较

int a = 5, b = 2;
System.out.println(a / b); // 2(余数被丢弃)

double aa = 5, bb = 2;
System.out.println(aa / bb); // 2.5

5. 使用 double 时的常见错误与“怪现象”

输入转换错误

经典场景:用户输入 3,14,而程序期望 3.14。在 Java 中,Scanner.nextDouble() 受当前区域设置(Locale)影响:在俄语/德语区域设置中,逗号可用;在英语区域设置中则需要点号。如有需要,可为 Scanner 设置相应的 Locale,或先读入字符串再手动解析。

// 在 Locale.US 下,如果输入 "3,14" 会出问题
double value = console.nextDouble();

计算机中的数字“非精确性”

这时新手通常会有些困惑:

double x = 0.1 + 0.2;
System.out.println(x); // 咦… 0.30000000000000004

恭喜你,遇到了计算机内部表示小数的“魔法”。许多数字在二进制系统中无法被精确表示。对大多数应用来说这通常无关紧要,但在金融和精密科学中就需要注意这些细节。

6. 重要:doubleint——自动与显式转换

当你把整数与小数相加,或把 int 赋给 double 变量时——不会报错:

int i = 2;
double d = i; // 一切正常!
System.out.println(d); // 2

double dd = 3.7;
int ii = (int) dd; // 需要显式将 double 转换为 int!
System.out.println(ii); // 3,小数部分被丢弃

这常常令人惊讶:为什么转换之后小数部分没了?原因很简单,类型 int 无法存储小数(小数点后的内容会被直接丢弃)。

关于将 double 转为 int 以及运算符 (int) 的更多内容,将在下一讲中介绍。

7. 格式化输出:优雅地输出 double

默认情况下,double 往往会带一堆没必要的尾随零。我们可以对输出进行格式化:

double temp = 23.56789;
System.out.println(temp); // 23.56789

// 保留 2 位小数
System.out.println(String.format("%.2f", temp)); // 23.57

// 保留 1 位小数
System.out.println(String.format("%.1f%n", temp)); // 23.6
格式 结果 说明
"%.2f"
23.57 保留 2 位小数的数字
"%.1f"
23.6 保留 1 位小数的数字

8. 使用 floatdouble 时的常见错误

错误 №1:将 double 隐式转换为 float

float f = 1.23; // 错误!

编译器会不高兴:“你正尝试把 double 放进 float——这可能导致精度丢失!”务必添加后缀 f

错误 №2:忘记了两个 int 相除得到的是 int 结果

int a = 7, b = 2;
double result = a / b; // 3.0,而不是 3.5

要得到小数部分,显式地把至少一个操作数转换为:

double result = (double) a / b; // 3.5

错误 №3:比较小数

不要使用 == 判断小数是否相等。应当使用带有很小容差(epsilon)的比较。

错误 №4:float 的精度丢失

不要在 float 中存放大数或需要高精度的值——它可能会“失真”或丢失关键数字。

1
任务
JAVA 25 SELF, 第 6 级, 课程 2
已锁定
计算宇宙飞船的平均速度 🚀
计算宇宙飞船的平均速度 🚀
1
任务
JAVA 25 SELF, 第 6 级, 课程 2
已锁定
智能售货机的付款接收 💰
智能售货机的付款接收 💰
1
任务
JAVA 25 SELF, 第 6 级, 课程 2
已锁定
在线商店商品价格格式化 🛍️
在线商店商品价格格式化 🛍️
1
任务
JAVA 25 SELF, 第 6 级, 课程 2
已锁定
在冒险家朋友之间分配魔法苹果 🍎
在冒险家朋友之间分配魔法苹果 🍎
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION