【问题标题】:How to extract fractional digits of double/BigDecimal [duplicate]如何提取double / BigDecimal的小数位[重复]
【发布时间】:2012-07-15 20:58:45
【问题描述】:

假设我们有一个双精度值12345.6789(应该是动态的)

现在的要求是拆分数字,得到小数位和小数位,即:

double number = 12345.6789;
int decimal = 12345;
int fractional = 6789;

我得到了小数部分,但请你给点小数部分的提示吗?非常感谢。

【问题讨论】:

  • 您需要确定是否要查找 打印 表示的小数部分,或者您是否愿意接受实际二进制文件中看似的准确性差异代表。
  • @seh 小数部分应该只包含不带空格的数字。
  • 唯一的方法是设置要使用的小数位数...示例有 2 个小数:0.01 为 1,0.10 为 10。看看我的答案。
  • 这不是完全重复的,因为这里要求整数的小数位数。

标签: java


【解决方案1】:
double number = 12345.6789; // you have this
int decimal = (int) number; // you have 12345
double fractional = number - decimal // you have 0.6789

这里的问题是小数部分在内存中不是写成“0.6789”,而是可能有一定的“偏移量”,可以这么说。例如0.6789 可以存储为0.67889999291293929991

我认为您在这里主要关心的不是获取小数部分,而是以一定的精度获取小数部分。

如果您想获得分配给它的确切值,您可能需要考虑这个(尽管如此,这不是一个干净的解决方案):

String doubleAsText = "12345.6789";
double number = Double.parseDouble(doubleAsText);
int decimal = Integer.parseInt(doubleAsText.split("\.")[0]);
int fractional = Integer.parseInt(doubleAsText.split("\.")[1]);

但是,正如我所说,这不是最有效和最干净的解决方案。

【讨论】:

  • 它需要一个用于拆分方法的正则表达式字符串参数。所以你需要使用“\\。”参考:stackoverflow.com/a/14833048/2000405
  • 对于“精确值”的第二种解决方案,如果小数部分以 0 开头,您将失去那些 0,最终得到一个非常不同的数字。
  • 适用于double,但不适用于Double
【解决方案2】:

你不能以精确的方式做你想做的事。

一个问题是如果你有号码1.05,结果应该是什么?

double number = 1.05;
int decimal = 1;
int fractional = 5; // Oops! "1.05" and "1.5" give the same result.

这个怎么样?

int fractional = 05; // Still not correct. This is an octal number.

另一个问题是双精度类型不能准确地表示12345.6789。相反,它存储了一个稍微不同的数字。这称为表示错误。所以小数部分实际上不会是6789。相反,您可以将其四舍五入到小数位数。

int fractional = (int)Math.round((number - decimal) * 1000);

【讨论】:

  • 不会一直有效,因为小数部分可以有 4 位以上 :)
  • @Mark Byers 谢谢你的解决方案,但是分数部分是动态的,所以我们不知道它有多长,所以 *1000 解决方案可能不起作用。如果双精度为 12345.678,则它变为 *100。
  • @Subarule:我没有给你解决方案,我给你解释了为什么不改变要求就不能完成。您愿意更改哪项要求?
  • @Mark Byers 可能会转换为字符串并处理并返回可能是一个解决方案?
【解决方案3】:

您必须决定支持多少小数。我用这个方法:

int decimals = 2;
BigDecimal value = new BigDecimal(123.45).setScale(decimals, RoundingMode.HALF_EVEN);
BigInteger INTEGER = value.abs().toBigInteger();
//(value - INTEGER) * (10 ^ decimais)
BigInteger DECIMAL = ((value.subtract(new BigDecimal(INTEGER))).multiply(new BigDecimal(10).pow(decimals))).toBigInteger();

【讨论】:

    【解决方案4】:

    您可以转换为String,找到小数点,获取子字符串,然后再转换回整数。

    String numberStr = Double.toString(number);
    String fractionalStr = numberStr.substring(numberStr.indexOf('.')+1);
    int fractional = Integer.valueOf(fractionalStr); 
    

    【讨论】:

    • 在 Double.toString 返回科学指数表示法时不起作用。
    猜你喜欢
    • 1970-01-01
    • 2016-10-04
    • 1970-01-01
    • 1970-01-01
    • 2017-07-26
    • 2011-03-25
    • 2016-11-21
    • 2011-02-18
    • 2011-05-26
    相关资源
    最近更新 更多