当前位置: 首页 > news >正文

2.4java运算需要注意的细节

扩展运算符在进行运算的同时会自动将结果强制转换回左侧变量的类型。

Java 中小于 int 类型的数据在进行算术运算时,会自动提升为 int 类型,这是为了避免溢出问题以及简化指令集。但使用扩展运算符时,其行为有一些特殊之处。扩展运算符在进行运算的同时会自动将结果强制转换回左侧变量的类型。

示例代码

public class ExtendedOperatorConversion {public static void main(String[] args) {// byte 类型使用扩展运算符byte b = 10;b += 5;System.out.println("byte 类型使用 += 后的结果: " + b);// short 类型使用扩展运算符short s = 20;s -= 3;System.out.println("short 类型使用 -= 后的结果: " + s);// char 类型使用扩展运算符char c = 'A';c *= 2;System.out.println("char 类型使用 *= 后的结果: " + c);// 普通运算符与扩展运算符对比byte normalByte = 10;// 普通加法运算,需要显式强制类型转换normalByte = (byte) (normalByte + 5);System.out.println("byte 类型使用普通 + 并强制转换后的结果: " + normalByte);}
}

代码解释

  1. byte 类型使用扩展运算符
    • b += 5 等价于 b = (byte)(b + 5)。在运算时,b 先被提升为 int 类型进行 b + 5 的运算,得到一个 int 类型的结果,然后扩展运算符会自动将结果强制转换回 byte 类型再赋值给 b
  2. short 类型使用扩展运算符
    • s -= 3 等价于 s = (short)(s - 3)。同样,s 先提升为 int 类型运算,结果再强制转换回 short 类型赋值给 s
  3. char 类型使用扩展运算符
    • c *= 2 等价于 c = (char)(c * 2)c 提升为 int 类型进行乘法运算,结果强制转换回 char 类型赋值给 c
  4. 普通运算符与扩展运算符对比
    • 使用普通运算符(如 +)进行运算时,由于运算结果是 int 类型,若要赋值给小于 int 类型的变量,需要显式地进行强制类型转换,如 normalByte = (byte) (normalByte + 5)

注意事项

  • 数据溢出风险:由于扩展运算符会自动进行强制类型转换,当运算结果超出左侧变量类型的取值范围时,会发生数据溢出。例如:
byte overflowByte = 120;
overflowByte += 10;
System.out.println("发生溢出的 byte 结果: " + overflowByte);

这里 120 + 10 的结果超出了 byte 类型的范围(-128 到 127),强制转换后会得到一个溢出的结果。

  • 代码可读性:虽然扩展运算符使用起来更简洁,但要清楚其背后的自动类型转换机制,避免因疏忽导致数据错误。在复杂运算场景中,显式的类型转换和普通运算符的使用可能会让代码更易理解

当进行整数运算时,其结果会是整数,小数部分会被直接舍去

原理

Java 中有多种整数类型,像 byteshortintlong 等。当使用这些整数类型进行运算时,Java 会按照整数的规则处理结果。由于整数类型无法存储小数部分,所以在运算结果为小数时,会直接舍弃小数部分,只保留整数部分,这种处理方式也被叫做截断取整。

示例代码

以下示例代码展示了不同整数运算中小数部分被舍去的情况:

public class IntegerArithmetic {public static void main(String[] args) {// 示例 1: 整数除法int dividend = 10;int divisor = 3;int result1 = dividend / divisor;System.out.println("10 除以 3 的整数运算结果: " + result1);// 示例 2: 多个整数运算int num1 = 20;int num2 = 7;int num3 = 4;int result2 = (num1 + num2) / num3;System.out.println("(20 + 7) 除以 4 的整数运算结果: " + result2);// 示例 3: 不同整数类型的运算long longNum = 100L;int intNum = 3;long result3 = longNum / intNum;System.out.println("100L 除以 3 的整数运算结果: " + result3);}
}

代码解释

  • 整数除法:在 10 / 3 这个运算里,数学上的结果是 3.333...,但因为是整数运算,小数部分被舍去,最终结果为 3
  • 多个整数运算:先计算 20 + 7 得到 27,再进行 27 / 4 的运算,数学结果是 6.75,舍去小数部分后结果为 6
  • 不同整数类型的运算:当 long 类型和 int 类型进行运算时,结果会自动提升为 long 类型,但同样会舍去小数部分。100L / 3 的数学结果是 33.333...,最终结果为 33

注意事项和其他情况

若要得到精确的小数结果,可以把参与运算的操作数至少一个转换为浮点数类型(如 float 或 double)。示例如下:

public class IntegerToFloatArithmetic {public static void main(String[] args) {int dividend = 10;int divisor = 3;double result = (double) dividend / divisor;System.out.println("10 除以 3 的精确结果: " + result);}
}

在上述代码中,将 dividend 强制转换为 double 类型,这样运算时就会按照浮点数的规则进行,得到的结果就是精确的小数 3.333...。在 Java 整数运算中,要时刻留意结果会舍去小数部分这一特性,依据具体需求选择合适的数据类型和运算方式

浮点数类型(float 和 double)在进行运算时会存在不精确性的问题

原因

计算机在存储和处理浮点数时,采用的是二进制表示法。然而,大多数十进制小数无法精确地用二进制表示,这就导致了浮点数在存储和运算过程中会出现精度损失。

以十进制小数 0.1 为例,它在二进制中是一个无限循环小数。由于计算机的存储空间有限,只能对其进行近似表示,这就使得在进行浮点数运算时,结果可能会出现微小的误差。

示例代码

public class FloatingPointPrecision {public static void main(String[] args) {// 示例 1: 简单的加法运算double num1 = 0.1;double num2 = 0.2;double result = num1 + num2;System.out.println("0.1 + 0.2 的结果: " + result);// 预期结果是 0.3,但实际输出可能不是精确的 0.3// 示例 2: 比较运算if (result == 0.3) {System.out.println("结果等于 0.3");} else {System.out.println("结果不等于 0.3");}}
}

代码解释

  • 加法运算:在上述代码中,0.1 和 0.2 相加的预期结果是 0.3,但由于浮点数的不精确性,实际输出的结果可能是一个接近 0.3 的值,如 0.30000000000000004
  • 比较运算:由于 result 的值不是精确的 0.3,所以在进行 result == 0.3 的比较时,结果为 false

解决方案

为了避免浮点数运算的不精确性问题,可以使用 java.math.BigDecimal 类。BigDecimal 类可以精确地表示和处理任意精度的十进制数。

import java.math.BigDecimal;public class BigDecimalExample {public static void main(String[] args) {// 创建 BigDecimal 对象BigDecimal bd1 = new BigDecimal("0.1");BigDecimal bd2 = new BigDecimal("0.2");// 进行加法运算BigDecimal sum = bd1.add(bd2);System.out.println("0.1 + 0.2 的精确结果: " + sum);// 比较运算BigDecimal expected = new BigDecimal("0.3");if (sum.compareTo(expected) == 0) {System.out.println("结果等于 0.3");} else {System.out.println("结果不等于 0.3");}}
}
  • 创建 BigDecimal 对象:使用字符串构造函数创建 BigDecimal 对象,这样可以避免浮点数的不精确性。
  • 加法运算:使用 add() 方法进行加法运算,得到精确的结果。
  • 比较运算:使用 compareTo() 方法进行比较,该方法返回 0 表示相等,返回负数表示小于,返回正数表示大于。

在需要精确计算的场景中,如金融领域,建议使用 BigDecimal 类来避免浮点数运算的不精确性问题。

相关文章:

  • JS-OCR-demo加载本地文件
  • springboot当中的类加载器
  • C20-breakcontinue
  • AOSP Android14 Launcher3——动画核心类QuickstepTransitionManager详解
  • OneNet云平台
  • 创建laravel 12项目
  • [GXYCTF2019]Ping Ping Ping
  • 驯龙日记:用Pandas驾驭数据的野性
  • 在AWS Glue中实现缓慢变化维度(SCD)的三种类型
  • 深圳市富力达:SAP一体化管理助力精密制造升级 | 工博科技SAP客户案例
  • 织梦dedecms网站如何修改上一篇下一篇的标题字数
  • 【Flutter】Flutter + Unity 插件结构与通信接口封装
  • 光场的相位与偏振
  • 详解 Unreal Engine(虚幻引擎)
  • 开源网络入侵检测与防御系统:Snort
  • Spark SQL开发实战:从IDEA环境搭建到UDF/UDAF自定义函数实现
  • Maven下载aspose依赖失败的解决方法
  • BeeWorks Meet更适合企业内部使用的原因
  • Linux中线程池的简单实现 -- 线程安全的日志模块,策略模式,线程池的封装设计,单例模式,饿汉式单例模式,懒汉式单例模式
  • streamlit实现非原生的按钮触发效果 + flask实现带信息的按钮触发
  • 央行副行长:研究建立民营中小企业增信制度,破解民营中小企业信用不足等融资制约
  • 人社部:就业政策储备充足,将会根据形势变化及时推出
  • 《九龙城寨之围城》斩获香港金像奖九项大奖,包括最佳影片
  • 起底网红热敷贴“苗古金贴”:“传承人”系AI生成,“千年秘方”实为贴牌货
  • 俄军方:已完成库尔斯克地区全面控制行动
  • 陈平评《艺术科学的目的与界限》|现代艺术史学的奠基时代