在 JSP/Java 中,如何从 double 获得整数和小数部分?

在 JSP/Java 中,如何从 double 获得整数和小数部分?如果值是3.25,那么我想得到 fractional =.25whole = 3

我们如何在 Java 中做到这一点?

175081 次浏览

最初的问题要求的是指数和尾数,而不是小数和整数部分。

要从一个双精度数中得到指数和尾数,你可以把它转换成 IEEE 754表示,然后像下面这样提取位:

long bits = Double.doubleToLongBits(3.25);


boolean isNegative = (bits & 0x8000000000000000L) != 0;
long exponent      = (bits & 0x7ff0000000000000L) >> 52;
long mantissa      =  bits & 0x000fffffffffffffL;
double value = 3.25;
double fractionalPart = value % 1;
double integralPart = value - fractionalPart;

[编辑: 最初的问题是如何得到尾数和指数。]

其中 N是得到实数尾数/指数的数字:

exponent = int(log(n))
mantissa = n / 10^exponent

或者,为了得到你想要的答案:

exponent = int(n)
mantissa = n - exponent

这些不完全是 Java,但应该很容易转换。

The mantissa and exponent of an IEEE double floating point number are the values such that

value = sign * (1 + mantissa) * pow(2, exponent)

如果尾数的形式为0.1010101 _ base 2(即其最重要的位被移动到二进制点之后) ,并且指数被调整为偏差。

从1.6开始,java.lang. Math 还提供了一个直接方法来获得无偏指数(称为 getExponent (double))

然而,你要求的数字是数字的整数和小数部分,这可以用

integral = Math.floor(x)
fractional = x - Math.floor(x)

虽然你可能想要区别对待负数 (floor(-3.5) == -4.0),这取决于你为什么想要这两个部分。

我强烈建议你不要把这些叫做尾数和指数。

Http://www.java2s.com/code/java/data-type/obtainingtheintegerandfractionalparts.htm

double num;
long iPart;
double fPart;


// Get user input
num = 2.3d;
iPart = (long) num;
fPart = num - iPart;
System.out.println("Integer part = " + iPart);
System.out.println("Fractional part = " + fPart);

产出:

Integer part = 2
Fractional part = 0.2999999999999998
public class MyMain2 {
public static void main(String[] args) {
double myDub;
myDub=1234.5678;
long myLong;
myLong=(int)myDub;
myDub=(myDub%1)*10000;
int myInt=(int)myDub;
System.out.println(myLong + "\n" + myInt);
}
}

Since this 1-year old question was kicked up by someone who corrected the question subject, and this question is been tagged with jsp, and nobody here was able to give a JSP targeted answer, here is my JSP-targeted contribution.

使用 JSTL(只需在 /WEB-INF/lib中删除 Jstl-1.2. jar) Fmt标签库。这里有一个 <fmt:formatNumber>标记,它可以准确地完成您想要的任务,并且在 maxFractionDigitsmaxIntegerDigits属性的帮助下以一种非常简单的方式完成。

这是 SSCCE,复制粘贴,然后运行。

<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>


<%
// Just for quick prototyping. Don't do this in real! Use servlet/javabean.
double d = 3.25;
request.setAttribute("d", d);
%>


<!doctype html>
<html lang="en">
<head>
<title>SO question 343584</title>
</head>
<body>
<p>Whole: <fmt:formatNumber value="${d}" maxFractionDigits="0" />
<p>Fraction: <fmt:formatNumber value="${d}" maxIntegerDigits="0" />
</body>
</html>

产出:

整数: 3

Fraction: .25

That's it. No need to massage it with help of raw Java code.

由于 fmt:formatNumber标记并不总是产生正确的结果,这里有另一种仅用于 JSP 的方法: 它只将数字格式化为字符串,并在字符串上执行其余的计算,因为这样更容易,而且不涉及进一步的浮点运算。

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>


<%
double[] numbers = { 0.0, 3.25, 3.75, 3.5, 2.5, -1.5, -2.5 };
pageContext.setAttribute("numbers", numbers);
%>


<html>
<body>
<ul>
<c:forEach var="n" items="${numbers}">
<li>${n} = ${fn:substringBefore(n, ".")} + ${n - fn:substringBefore(n, ".")}</li>
</c:forEach>
</ul>
</body>
</html>

主要逻辑你必须首先找到有多少位数字后有小数点。
此代码适用于任何数字高达16位。如果使用 BigDecimal,最多可以运行18位。把输入值(你的数字)放到变量“ num”中,作为一个例子,我已经硬编码了它。

double num, temp=0;
double frac,j=1;


num=1034.235;
// FOR THE FRACTION PART
do{
j=j*10;
temp= num*j;
}while((temp%10)!=0);


j=j/10;
temp=(int)num;
frac=(num*j)-(temp*j);


System.out.println("Double number= "+num);
System.out.println("Whole part= "+(int)num+" fraction part= "+(int)frac);

不知道这样是否更快,但我正在使用

float fp = ip % 1.0f;

许多答案都有可怕的舍入错误,因为它们把数字从一种类型转换成另一种类型。这个怎么样:

double x=123.456;
double fractionalPart = x-Math.floor(x);
double wholePart = Math.floor(x);

The accepted answer don't work well for negative numbers between -0 and -1.0 也给小数部分负数。

例如: 0号,35号

报税表

Integer part = 0 小数部分 = -0.35

If wou are working with GPS coordinates it is better to have a result with the signum on the integer part as:

整数部分 = -0 小数部分 = 0.35

这些数字用于例如 GPS 坐标,其中对于 Lat 或 Long 位置很重要

建议代码:

    double num;
double iPart;
double fPart;


// Get user input
num = -0.35d;
iPart = (long) num;
//Correct numbers between -0.0 and -1.0
iPart = (num<=-0.0000001 && num>-1.0)? -iPart : iPart ;
fPart = Math.abs(num - iPart);
System.out.println(String.format("Integer part = %01.0f",iPart));
System.out.println(String.format("Fractional part = %01.04f",fPart));

产出:

Integer part = -0
Fractional part = 0,3500

从 Java8开始,您可以使用 Math.floorDiv

它返回小于或等于代数商的最大(最接近正无穷大) int值。

一些例子:

floorDiv(4, 3) == 1
floorDiv(-4, 3) == -2

或者,可以使用 /操作符:

(4 / 3) == 1
(-4 / 3) == -1

参考文献:

我会用 BigDecimal 来解决这个问题,像这样:

    double value = 3.25;
BigDecimal wholeValue = BigDecimal.valueOf(value).setScale(0, BigDecimal.ROUND_DOWN);
double fractionalValue = value - wholeValue.doubleValue();
String value = "3.06";


if(!value.isEmpty()){
if(value.contains(".")){
String block = value.substring(0,value.indexOf("."));
System.out.println(block);
}else{
System.out.println(value);
}
}

如果你的数字是2.399999999999999999,我假设你想得到精确的十进制值,那么使用 BigDecimal:

Integer x,y,intPart;
BigDecimal bd,bdInt,bdDec;
bd = new BigDecimal("2.39999999999999");
intPart = bd.intValue();
bdInt = new BigDecimal(intPart);
bdDec = bd.subtract(bdInt);
System.out.println("Number : " + bd);
System.out.println("Whole number part : " + bdInt);
System.out.println("Decimal number part : " + bdDec);
// target float point number
double d = 3.025;


// transfer the number to string
DecimalFormat df = new DecimalFormat();
df.setDecimalSeparatorAlwaysShown(false);
String format = df.format(d);


// split the number into two fragments
int dotIndex = format.indexOf(".");
int iPart = Integer.parseInt(format.substring(0, dotIndex)); // output: 3
double fPart = Double.parseDouble(format.substring(dotIndex)); // output: 0.025

好吧,这可能有点晚了,但我认为最好和更准确的方法是使用 BigDecimal

double d = 11.38;


BigDecimal bigD = BigDecimal.valueOf(d);
int intPart = bigD.intValue();
double fractionalPart = bigD.subtract(BigDecimal.valueOf(intPart)).doubleValue();


System.out.println(intPart); // 11
System.out.println(fractionalPart ); //0.38