1. 精度
浮点类型是不精确存储的
示例:
@Test
public void decimalTest() {
// 0.1 + 0.2 = 0.30000000000000004
System.out.println("0.1 + 0.2 = " + (0.1 + 0.2));
double d = 0.1 + 0.2;
BigDecimal decimal = new BigDecimal(d);
// decimal: 0.3000000000000000444089209850062616169452667236328125
System.out.println("decimal: " + decimal);
System.out.println("new BigDecimal(0.1): " + new BigDecimal(0.1));
}
@Test
public void decimalTest() {
for (int i = 1; i <= 9; i++) {
double d = Double.parseDouble("0." + i);
System.out.println(d);
BigDecimal bd = new BigDecimal(d);
System.out.println(bd);
}
// 能正常表示的只有 0.5
}
2. 二进制能准确表示的小数
@Test
public void binaryDecimal() {
int limit = 9999;
int length = String.valueOf(limit).length();
System.out.println("0.0001~0.9999之间可以使用二进制来准确表示的小数有:");
for (int i = 1; i <= limit; i++) {
int num0 = length - String.valueOf(i).length();
StringBuilder value = new StringBuilder("0.");
for (int j = 1; j <= num0; j++) {
value.append("0"); // 缺失的补0
}
value.append(i);
BigDecimal db = new BigDecimal(Double.parseDouble(value.toString()));
// 比较小数位数
if (db.scale() <= length) {
System.out.println(db);
}
}
}
3. 求整数的位数
方式一:log函数
/*
* 求整数的位数
* Math.log10(double)
* 对数:log10(100) = 2 等价 10^2=100
* Math.log10(9999) 从整型到浮点类型的转换可以隐式进行
*
* Math.ceil(double) 向上取整
*/
int limit = 999;
System.out.println(Math.log10(limit));
int len = (int) Math.ceil(Math.log10(limit));
// 其他
System.out.println(Math.ceil(1.01) + ", " + Math.ceil(1.8) + ", " + Math.ceil(-1.2) + ", " + Math.ceil(-1.8));
方式二:转成字符串求长度
int limit = 999;
int length = String.valueOf(limit).length();
4. 扩展问题
float 类型在Java中占用4字节,long类型在Java中占用8字节,为什么float类型的取值范围比long类型的取值范围还大?
分析:
float 的指数取值范围为-126~127,即 float的取值范围为-2^128 ~ +2^128
long 类型范围 -2^63 ~ 2^63-1
double 的取值范围 -2^1024 ~ +2^1024
类 型 | 符 号 位 | 指 数 域 | 有效位数域(小数位) |
---|---|---|---|
float | 1位(第31位) | 8位(第23~30位) | 23位(第0~22位) |
double | 1位(第63位) | 11位(第52~62位) | 52位(第0~51位) |
说明:
符号位有两个取值,0为正,1为负
网友评论