Dart/Flutter中Intl包NumberFormat反直觉结果及整数位移除咨询
问题解答
为什么NumberFormat(".##").format(17.46)返回17.46而非.46?
这是因为DecimalFormat(NumberFormat的常用实现类)的模式规则决定的:当你写.##时,小数点前的部分隐含了至少需要显示存在的整数位。也就是说,只要数字有非零的整数部分,它就会完整输出这部分;只有当整数部分为0时,才会省略前面的0,直接输出小数部分(比如format(0.46)会得到.46)。
简单说,.##的模式并没有告诉格式化器“隐藏所有整数部分”,而是说“如果整数部分存在,就显示它;小数部分保留两位”。
如何实现移除小数点前所有数字的需求?
这里有两种可靠的方案,根据你的场景选择:
方案1:提取小数部分后格式化
先把数字的整数部分去掉,只保留小数部分,再用格式化器处理:
double input = 17.46; // 提取小数部分:原数减去整数部分(Math.floor取小于等于原数的最大整数) double fractionalPart = input - Math.floor(input); // 用DecimalFormat格式化小数部分 DecimalFormat formatter = new DecimalFormat(".##"); String result = formatter.format(fractionalPart); // 输出结果:.46
这个方案的好处是直接针对数字本身处理,避免字符串操作可能带来的精度问题,而且能自动处理小数位数的保留(比如输入17.4会变成.40)。
方案2:格式化后截取字符串
先把数字格式化为保留两位小数的字符串,再截取小数点及后面的部分:
double input = 17.46; DecimalFormat formatter = new DecimalFormat("#.##"); String formattedStr = formatter.format(input); // 得到"17.46" // 找到小数点位置,截取后面的部分 int dotPos = formattedStr.indexOf('.'); String result = dotPos != -1 ? formattedStr.substring(dotPos) : ".00"; // 输出结果:.46
注意:如果输入是整数(比如17),formattedStr会是"17",这时候需要根据需求处理,比如返回.00或者其他默认值。
内容的提问来源于stack exchange,提问作者Heikkisorsa
相关产品推荐
相关产品推荐

