如何将double类型转换为int类型且舍弃小数部分不四舍五入?
解决Double转Int时的精度问题(完全舍弃小数部分)
我懂你遇到的这个坑——当你有一个像1.9999999999999999这样的double值时,不管是强制转int、Math.floor()还是格式化,结果都变成了2,但你明明只想保留整数部分1对吧?
这其实不是转换方法的问题,而是浮点数的精度限制导致的:1.9999999999999999这个值在Java的double存储里,实际上已经等于2.0了——因为double的二进制表示无法精确存储所有十进制小数,当数值足够接近下一个整数时,就会被“舍入”成那个整数。
下面给你几个可行的解决方案,适配不同的场景:
方案1:用BigDecimal做精确处理(最稳妥)
如果你的场景需要绝对精确的整数提取,BigDecimal是最佳选择,它能避开浮点数的精度陷阱:
import java.math.BigDecimal; import java.math.RoundingMode; public class ColumnCalculator { public static void main(String[] args) { double testValue = 1.9999999999999999; // 关键:用Double.toString()转字符串后再创建BigDecimal,避免直接传double的精度丢失 BigDecimal bd = new BigDecimal(Double.toString(testValue)); // RoundingMode.DOWN表示直接舍弃小数部分,不管小数是多少 int integerPart = bd.setScale(0, RoundingMode.DOWN).intValue(); System.out.println(integerPart); // 输出1,符合预期 } }
方案2:针对计算结果做阈值判断(适合你的列数计算场景)
你的列数是通过columnContainerHBox/minimalColumnWidth计算出来的,这种场景可以先判断数值是否因为精度问题“接近”下一个整数,再调整:
double columnContainerHBox = ...; // 你的容器宽度 double minimalColumnWidth = ...; // 列的最小宽度 double result = columnContainerHBox / minimalColumnWidth; int columnCount; // 定义一个极小的阈值,用来判断是否是精度导致的"伪整数" double epsilon = 1e-9; if (Math.abs(result - Math.floor(result)) < epsilon) { // 如果result和它的floor值差极小,说明是精度问题,直接取floor值 columnCount = (int) Math.floor(result); } else { // 普通情况直接强转,因为强转本身就是舍弃小数 columnCount = (int) result; } // 后续的边距计算逻辑(修正了你原来的公式错误) int numberOfMargins = columnCount - 1; double totalWidth = minimalColumnWidth * columnCount + columnMargin * numberOfMargins; // 正确的验证逻辑:判断总宽度是否超过容器宽度 if (totalWidth > columnContainerHBox) { columnCount--; }
方案3:微小偏移后用Math.floor(简单但需注意阈值)
如果场景对精度要求没那么高,可以先给数值减去一个极小的偏移量,再用Math.floor:
double testValue = 1.9999999999999999; // 减去一个极小的数,把"伪2.0"拉回真实的接近1的数值 int integerPart = (int) Math.floor(testValue - 1e-12); System.out.println(integerPart); // 输出1
这个方法的关键是选择合适的偏移阈值(比如1e-12),不能太大,否则会把正常的2.0变成1.999999999999,导致错误的结果。
内容的提问来源于stack exchange,提问作者Alyona
相关产品推荐
相关产品推荐

