《从C/C++到Java入门指南》- 7.浮点数运算

浮点数运算

引言

浮点数在计算机中难以进行精确表示,例如:0.1 换算成二进制是一个无限循环的小数,无论是double 还是float,都只能存储一个近似的值。但是0.5却可以进行精确的表示。

误差

浮点数的运算时常伴有误差:

public class Hello {
	public static void main(String[] args) {
		double x = 1.0 / 10;
		double y = 1 - 9.0 / 10;
		System.out.println(x);
		System.out.println(y);		
	}
}

结果如下:

image-20240717184917219

同样的,比较两个浮点数,也会发生误差:

public class Hello {
	public static void main(String[] args) {
		double x = 1.0 / 10;
		double y = 1 - 9.0 / 10;
		System.out.println(x == y);
	}
}

输出:false

正确的判断两个浮点数是否相等的方法是判断两个浮点数的差是否小于一个很小的数。

public class Hello {
	public static void main(String[] args) {
		double x = 1.0 / 10;
		double y = 1 - 9.0 / 10;
		double sub = Math.abs(x - y);
		if (sub < 1e-5) {
			System.out.println("相等!");
		} else {
			System.out.println("不相等!");
		}
	}
}

输出:相等

浮点数在计算机内存中的表示方法比整数要复杂,且完全遵循IEEE-754标准。

类型提升

需要注意的是,整数和浮点数进行运算也会自动类型提升,变成一个浮点数。

public class Hello {
	public static void main(String[] args) {
		int x = 10;
		float y = 1f;
		System.out.println(x + y);	// 输出 11.0
	}
}

但是,整数之间的运算是不会自动提升类型的,在复杂的四则运算中也是如此。

// 计算1 + .. + 100
public class Hello {
	public static void main(String[] args) {
		System.out.println(1f + 24 / 5);	// 输出 5.0
	}
}

可见,式子中的 24 / 5 = 4,4 + 1f = 5f,最后输出了 5.0

溢出

如果你用浮点数除以 0,不会得到报错,而是会得到几个奇怪的值。

public class Hello {
	public static void main(String[] args) {
		System.out.println(1f / 0);	 // Infinity
		System.out.println(0.0 / 0); // NaN
		System.out.println(-1f / 0); //	-Infinity
	}
}
  • NaN表示 Not a Number
  • Infinity 表示无限
  • -Infinity表示负无限

强制转型

将浮点型强制转成整型会抹去小数点后面的数,如果超过整型能表示的最大范围,只会返回整型的最大值。

public class Hello {
	public static void main(String[] args) {
		int x = (int) 12.7;
		System.out.println(x);
		
		int y = (int) -12.7;
		System.out.println(y);	// 转型后抹去小数部分
		
		int z = (int) 1.2e20;
		System.out.println(z);	// 溢出会返回整型的最大值
	}
}

如果需要进行四舍五入,可以对浮点数加上 0.5 后进行转型。

public class Hello {
	public static void main(String[] args) {
		int x = (int) (1.2f + 0.5);	// 得到 1
		System.out.println(x);
		
		int y = (int) (1.6f + 0.5);	// 得到 2
		System.out.println(y);
	}
}

练习

根据一元二次方程的求根公式,计算出方程的两个解。

答案

public class Hello {
	public static void main(String[] args) {
		double a = 1.0;
		double b = 3.0;
		double c = -4.0;
		double ans1 = (-b + Math.sqrt(b * b - 4 * a * c))/(2*a);
		double ans2 = (-b - Math.sqrt(b * b - 4 * a * c))/(2*a);
		
		System.out.println(ans1);	// 1.0
		System.out.println(ans2);	// -4.0
	}
}
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值