long与double混合运算时结果类型为double,因Java二元数字提升规则将long拓宽为double;虽转换合法,但超过2⁵³时存在精度丢失风险。

Java 中 long 和 double 混合参与算术运算时,结果类型由类型提升规则决定,而非“运算符优先级”本身——优先级只影响表达式求值顺序(如先乘除后加减),不改变操作数的类型转换行为。
long 与 double 运算会自动提升为 double
当 long 和 double 出现在同一二元算术运算(如 +、-、*、/)中时,Java 会将 long 值**拓宽(widening)转换为 double**,然后执行 double 运算,最终结果类型为 double。
- 这是 Java 语言规范定义的“二元数字提升”(Binary Numeric Promotion)规则的一部分
- 该转换是无损的语义保证(
double可精确表示所有long值,只要其绝对值 ≤ 2⁵³) - 例如:
long a = 100L; double b = 3.14; var result = a + b;→result类型为double
运算符优先级不影响类型选择,只影响结合顺序
比如表达式 10L + 2.0 * 3L:
- 先按优先级计算
2.0 * 3L:3L 提升为double,得6.0(double) - 再计算
10L + 6.0:10L 提升为double,得16.0(double) - 整个表达式结果仍是
double,且每一步的类型提升独立发生
注意精度丢失的隐含风险
虽然 long → double 是合法拓宽,但 double 的有效精度只有约 15–17 位十进制数字。当 long 值超过 2⁵³(≈ 9.007 × 10¹⁵)时,部分整数值无法被 double 精确表示:
立即学习“Java免费学习笔记(深入)”;
long x = 9007199254740992L; // 2^53double d = x + 1; // 结果仍是 9007199254740992.0 —— +1 丢失了- 这种误差在金融、计数等场景中需特别警惕
如需保持 long 精度,应避免与 double 混用
若业务逻辑要求整数精度(如 ID 计算、原子计数),建议:
- 统一使用
long,必要时用BigDecimal或自定义整数运算 - 避免将大范围
long直接与double相加/相减,除非明确接受浮点近似 - 编译器不会警告此类转换,需靠代码审查或静态分析工具(如 ErrorProne)识别潜在问题










