不使用 SetRoundingMode() 截断浮点值
Posted
技术标签:
【中文标题】不使用 SetRoundingMode() 截断浮点值【英文标题】:Truncating a Float Value Without Using SetRoundingMode() 【发布时间】:2012-05-04 07:34:54 【问题描述】:我在这里截断一个浮点数。但我的值正在四舍五入。我不想要那个。例如,如果我的值是 12.989 -> 它应该只打印为 12.98。有人可以帮忙吗 我不能使用十进制格式的 SetRoundingMode,因为它仅受 java 1.6 支持。 我的是 1.5 JDK。有人可以在不使用 SetRoundingMode() 方法的情况下帮助我吗????
String pattern = "##,##0.00";
NumberFormat nf = NumberFormat.getNumberInstance();
DecimalFormat df = (DecimalFormat)nf;
double fPart;
Float value=233.989f;
String dstr = String.valueOf(value);
dstr = dstr.substring(dstr.indexOf(".")+1);
Long db = Long.valueOf(dstr);
if(db > 0)
df.applyPattern(pattern);
System.out.println("input="+value+", fPart="+dstr);
String output = df.format(value);
System.out.println(output);
【问题讨论】:
【参考方案1】:你总是可以使用老派的把戏,乘以 10^n,截断,除以 10^n:
float x = 233.989f;
x = (float)(Math.floor(x * 100) / 100);
我也尝试过 BigDecimal:
MathContext mc = new MathContext(5, RoundingMode.FLOOR)
BigDecimal decimal = new BigDecimal(233.989, mc);
System.out.println(decimal);
它可以完成这项工作,但您必须指定总位数。你不能只说我想要 2 位小数,我不在乎小数点后面的数字。这样MathContext
的第一个参数是5,而不是2。如果你选择这种方法,你可以用Math.Ceil(Math.log10(x))
快速计算非十进制数字。
注意:
除法(第一种方法)时,至少有一个操作数必须是浮点数(float 或 double) 在使用字符串(您编写代码)时,假定 '.' 是不安全的。是小数分隔符 使用 Math.floor 截断小数仅适用于正值【讨论】:
如果您不知道数字是什么,但仍想实现该模式怎么办? “老派把戏”的失败率超过 90%。您不能将浮点值截断为特定的小数位数,因为它们没有要截断的小数位。 @Azfar:你的意思是你必须知道这些数字是什么意思?您始终可以为MathContext
对象计算 setPrecision
。我是否必须澄清如何做到这一点? @EJP:如果我们稍微改变常量,乘法和除法都将以双精度执行:Math.floor(x * 100.0) / 100
。 AFAIK double
没有显示前 15 位数字的精度损失,我很漂亮,这对于 99% 的非科学微积分来说已经绰绰有余了。
@EmperorOrionii 当像 Math.floor(9.62 * 100 ) /100 这样的位数已经为 2 时,旧技巧不起作用,结果为 9.61【参考方案2】:
不确定我是否理解您的问题。但是如果你想截断而不向上或向下舍入,你可以使用就像
DecimalFormat df = new DecimalFormat("##.##");
df.format(12.912385);
【讨论】:
【参考方案3】:您可以使用正则表达式来获取“.”之后的第二个数字。然后将字符串从开头减去该位置,然后将字符串转换为浮点数或双精度数。
Pattern pattern = Pattern.compile("regular expression");
Matcher matcher = pattern.matcher("your string");
if(matcher.find())
int poz_begin = matcher.start();
int poz_end = matcher.end();
【讨论】:
不是正则表达式。以上是关于不使用 SetRoundingMode() 截断浮点值的主要内容,如果未能解决你的问题,请参考以下文章
在 X87 和 SSE FPU 中用户定义的点之后截断浮点数和双精度数