第1关:计算复利值
任务描述
本关任务:编写一个程序,先后输入本金金额以及年利率,输出未来 6 个月的账户金额。
相关知识
为了完成本关任务,你需要掌握:
- 数值类型;
- 从键盘读取数值;
- 数值操作符。
数值类型
数值是程序“计算”最基本的类型,也是我们用数学模型解决问题最基础的工具。 Java 提供了六种数值类型来描述浮点数和整数。
这六种类型如下表所示:
类型名 | 范围 | 存储大小 |
---|---|---|
byte | -2^7 ~ 2^7-1 | 8 位带符号整数 |
short | -2^15 ~ 2^15-1 | 16 位带符号整数 |
int | -2^31 ^ 2^31-1 | 32 位带符号整数 |
long | -2^63 ~ 2^63-1 | 64 位带符号整数 |
float | 32 位,标准 IEEE 754 | |
double | 64 位,标准 IEEE 754 |
表格列举的 6 中数值类型中,byte
、short
、int
、long
是整数型数值类型,他们的区别是取值范围的区别(存储位数越大,范围越大)。剩下的float
、double
是浮点型数据类型,他们的区别除了取值范围外,还有精度上的区别(double
的位数高,范围大,精度高)。
用整型描述整数存在的问题是范围有限,超过描述范围的数将无法用整型描述(这个问题将作为课程后续实训中的一个问题来解决)。
用浮点型描述小数存在的主要问题是精度问题,我们知道实数是连续不可数的集合,因此必然存在大量的实数无法用浮点型准确描述,只能近似描述。因此浮点数误差问题是我们在编程中经常会遇到的问题。
从键盘读取数值
上一小节介绍了 6 中数值类型以及他们各自的特点及使用时存在的问题,这一小节将介绍如何用变量存储这六种数值,以及 Java 程序如何从键盘获取行应数值。这一点在本课程的任务中会大量用到。
示例如下:
/** 代码清单 1 */
// 声明并创建从控制台的标准输入,从而读取键盘的输入
Scanner input = new Scanner(System.in);
// 声明 byte 类型变量 b,存储读取的 byte 类型数据
byte b = input.nextByte();
// 声明 short 类型变量 s,存储读取的 short 类型数据
short s = input.nextShort();
// 声明 int 类型变量 i,存储读取的 int 类型数据
int i = input.nextInt();
// 声明 long 类型变量 l,存储读取的 long 类型数据
long l = input.nextLong();
// 声明 float 类型变量 f,存储读取的 float 类型数据
float = input.nextFloat();
// 声明 double 类型变量 d,存储读取的 double 类型数据
double d = input.nextDouble();
代码清单 1
展示了如何从键盘读取数值型数据,你可以自己试着编写一个简单的程序,读取数据,并用System.out
在控制台打印你读取的内容。
数值操作符
我们已经知道如何读取并用变量存储数值类型了,那么接下来就需要操作这些数据,这就需要用到 Java 提供的数值操作符:
+
,加法运算,a+b
会产生变量a,b
中的值的相加的结果;-
,减法运算,a-b
会产生变量a,b
中的值的相减的结果;*
,乘法运算,a*b
会产生变量a,b
中的值的相乘的结果;/
,除法运算,a/b
会产生变量a,b
中的值的相除的结果;%
,求余运算,a%b
会产生变量a,b
中的值的相除后的余数结果,且a,b
必须都是整型。
需要注意的是,+
、-
、*
、/
可以同时针对整型以及浮点型使用,限制是 /
操作的除数不能为0
或0.0
。另外,/
操作的两个操作数都是整数时,会进行整数除法,结果是忽略余数的商,例如如下代码:
/** 代码清单 2 */
// 声明整型被除数
int a = 100;
// 声明整型除数
int b = 3;
// 声明整型变量,保存除法的结果
int c = a/b;
// 打印结果
System.out.print(c)
输出: 33
在代码清单 2
中,整型变量c
保存了除法结果,这是合法的。当然,也可以用浮点型保存除法结果,但不会影响除法的结果,示例如下:
/** 代码清单 3 */
// 声明整型被除数
int a = 100;
// 声明整型除数
int b = 3;
// 声明整型变量,保存除法的结果
float c = a/b;
// 打印结果
System.out.print(c)
输出: 33.0
在代码清单 3
中,a/b
实际上产生的是一个整型int
的结果,但却成功赋值给了float
类型的c
,这个过程之所以合法,是因为发生了强制类型转换,因此相较于代码清单 2
,结果从33
变成了33.0
。
注:强制类型转换是程序中会经常涉及到的概念或现象,课程后续章节会进行讲解。
编程要求
根据提示,在右侧编辑器 Begin-End 区域补充代码,按要求计算复利值并打印结果。具体要求如下:
-
变量
capital
、interest
分别存储着本金值,年利率(%)的值,它们的类型均为double
类型; -
计算出月利率,计算方式为: 年利率 / 12;
-
按月复利,依次计算出当前 6 个月,每个月账户上的金额,并逐行打印,保存小数点后 2 位。
以下提供一个计算范本:
本金 100,年利率 12%; 月利率 = 0.12/12 = 0.01; 按月复利时, 第一个月的账上金额:100 * (1+0.01) = 101; 第二个月的账上金额: 101 * (1+0.01) = 102.01; 第三个月的账上金额: 102.01 * (1+0.01) = 103.0301; …… 依次类推。
测试说明
平台会对你编写的代码进行测试:
测试输入:
100
,12
;预期输出:
100 12
101.00
102.01
103.03
104.06
105.10
106.15
提示: 格式化输出,保留 2 位小数
double a = 1.0015
System.out.println(String.format(".2f", a));
输出:
1.00
代码如下
package step1;
import java.util.Scanner;
public class Main
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
// 输入本金
double capital = input.nextDouble();
// 输入利息
double interest = input.nextDouble();
input.close();
//请在指定位置填写代码。
/********* Begin *********/
double a,b,c,d,e,f;
double x;
x=interest/1200;
a=capital*(1+x);
System.out.println(String.format("%.2f", a));
b=a*(1+x);
System.out.println(String.format("%.2f", b));
c=b*(1+x);
System.out.println(String.format("%.2f", c));
d=c*(1+x);
System.out.println(String.format("%.2f", d));
e=d*(1+x);
System.out.println(String.format("%.2f", e));
f=e*(1+x);
System.out.println(String.format("%.2f", f));
/********* End *********/
}
}
第2关:计算整数各位和
任务描述
本关任务:进一步了解 Java 的其他数据类型,并根据所学实现程序功能:输入一个不超过 7 位的整数,输出各个位上的数字和。
相关知识
为了完成本关任务,你需要掌握:
- 如何获取各位上的数字;
- Java 的其他数据类型;
- Java 的其他数值操作。
如何获取各个位上
本关编程任务的要求是计算整数(十进制)各位上的数字和,例如整数123456
,我们需要计算出的结果是1+2+3+4+5+6=21
。
这里的关键问题是,如和取出各个位上的数字? 其实,使用上一关中介绍的/
以及%
操作符就能轻松实现这一目标。 示例如下:
/** 代码清单 1*/
int number = 21;
int bit1 = number % 10;
System.out.print(bit1);
输出:
1
代码清单 1
输出的变量bit1
的值就是数字21
个位上的值。接下来,将展示如何取十位上的值。
示例如下:
/** 代码清单 2*/
int number = 21;
// 进行一次整数除法,此时 number2 中保存的值为 2
int number2 = number/10;
int bit2 = number2 % 10;
System.out.print(bit2);
输出:
2
可以看出,代码清单 2
成功输出了数字21
十位上的值。实际上,通过/10
操作相当于将十位上的数字降至个位,再按照代码清单 1
的套路,就能取出十位上的值了。
按照这样的思路,用number/100
操作来取百位上的数字,用number/1000
操作来取千位上的数字,……,用number/1000000
操作来取百万位上的数字。
取出各个位上的数字,求和就很简单了,这里不再赘述。
Java 的其他数据类型
Java 除了提供了数值类型,还提供了一些其他的数据类型,通过思考以下问题,将引出这些数值类型之外的数据类型。
上一小节讲解了如何解决本关任务的关键问题,不知道能否引起你的一些思考:
-
如果将十进制数,换成十六进制,该如何解决? 我们知道,十六进制数字表示除了
0~9
外,还有A~F
,这已经不是现有数值型数据能够表示的,那么这些数据要怎么表示呢?实际上,Java 还提供了char
类型来表示字符,采用 Unicode 编码,能够表示我们使用使用的绝大多数文本符号。字符数据类型和操作将在本课程第 06 章-第 02 节进行详细讲解。 -
如果问题不限制最大位数,该如何解决? 这其实是整型数据类型面临的一个问题,即超过表示范围的数,该如何表示。实际上 Java 还提供了数组的概念,使用数组,原则上就能存储任意大的整数了。Java 数组将在本课程第 07 章-第 01 节开始进行详细的讲解。
-
如果不限制位数,如何判断取数过程结束? 其实,如果不限制位数,理论上取数的操作永远不会结束,但实际中是有结束条件的,如何描述这个条件就是这个问题的关键问题。相应的,Java 提供了布尔类型来描述条件状态判断,这部分内容将在第 03 章-第 01 节进行详细讲解。
虽然引出了这么多的问题,但还请耐心根据本课程安排的进度学习下去,打牢基础,学习进程会比你想像的要快。
Java 的其他数值操作
目前为止,我们介绍了数值类型的五种操作符,并使用它们解决了一些问题。但实际上,还有很多的问题仅用现阶段介绍的操作符难以解决。例如幂运算、开方运算、三角函数等。对于这些复杂的数学运算,Java 提供了一个类Math
来进行实现,这部分内容将在第 04 章-第 01 节进行详细讲解。
编程要求
根据提示,在右侧编辑器 Begin-End 区域补充代码,具体要求如下:
-
变量
number
表示一个不超过 7 位的十进制整数; -
计算各个位上的数字和之后输出结果。
测试说明
平台会对你编写的代码进行测试:
测试输入:
123456
;预期输出:
21
提示: 结果输出后无换行。
代码如下
package step2;
import java.util.Scanner;
public class Main
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
// 输入十进制整数
int number = input.nextInt();
input.close();
//请在指定位置填写代码。
/********* Begin *********/
int shu;
int ci=0;
while(number>0)
{
shu=number%10;
ci+=shu;
number/=10;
}
System.out.print(ci);
/********* End *********/
}
}