ChatGPT解决这个技术问题 Extra ChatGPT

如何从 JSP/Java 中的 double 中获取整数和小数部分?

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

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

您似乎对尾数和指数是什么有一个不准确的想法。它们不仅仅是“整体”和“部分”。请参阅en.wikipedia.org/wiki/Floating_point
实际上,在“嘿……那不叫指数”之前,我阅读了大约 5 篇文章。我的大脑抛出了单词并开始解决问题..阅读编程材料的坏习惯给了我:)
此外,出于其他原因,请重新表述问题 OP..。
听起来像是一个家庭作业问题。
哦,我明白了。我已经想知道他是如何得到如此奇怪的结果的

D
Dan Vinton
double value = 3.25;
double fractionalPart = value % 1;
double integralPart = value - fractionalPart;

为什么这被否决了?工作正常,我的编辑也适用于负值。
整数部分可以是 => long longPart = (long)3.25
不会为负数工作。价值观。即 -3.25 % 1 = 0.75 而不是 0.25。所以integralPart 将是-3.25 - 0.75 = -4。
@WindRider,我检查了负数..及其作品..但是对于数量较少的小数位,会有一点错误。前任。对于 -03.0025 它返回 -0.0024999999999999467 和 -3.0
这里的混淆是因为某些语言,例如 Python,使用 % 来表示模数 (-3.25 % 1 == 0.75),而其他语言,例如 Java、Fortran、C 和 C++,使用 % 来表示余数 (-3.25 % 1 == -0.25) . WindRider 可能为了方便起见已将其键入 Python REPL,但该答案具有误导性,因为此问题与 JVM 有关。
D
Dan Is Fiddling By Firelight

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

实际上,此页面是谷歌搜索“从双 java 中获取部分和全部部分”的第一次点击=)
实际上这个答案是不正确的,因为大于 long 的值可以表示它会在小数部分给出大量数字。下面的 Dan Vinton 回答同样简单,并且总是返回正确的结果。
所以实际上,这是不正确的,正如您在输出中看到的那样。输入是 3 的分数,输出是 29999999...虽然使用 BigDecimal 而不是 Double 可以解决问题
@Alex不,输入是一个非常接近2.3的数字,但肯定不是2.3。并且输出没有任何问题,除非您想要超过 10 个有效数字。您只需要在每个输出中进行一些舍入(例如,格式 %.9f),这通常比 BigDecimal 更轻松。这里唯一的问题是溢出。
将 double 转换为 int 几乎总是一个坏主意。因为例如对于 (long)1.0e100,您将得到 0。很多时候,您需要的 double 值只是“下限”,其中有 floor()。如果您想要整数部分和分数部分,请使用 modf()。真的,这是一个糟糕的答案。
B
BalusC

由于这个1年前的问题是由更正问题主题的人提出的,并且这个问题被标记为jsp,这里没有人能够给出JSP针对性的答案,这里是我的JSP-targeted贡献。

使用 JSTL(只需将 jstl-1.2.jar 放入 /WEB-INF/libfmt 标签库。在 maxFractionDigitsmaxIntegerDigits 属性的帮助下,有一个 <fmt:formatNumber> 标记可以非常简单地完成您想要的操作。

这是一个 SSCCE,只需复制'n'粘贴'n'运行它。

<%@ 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 分数:0.25

而已。无需借助原始 Java 代码对其进行按摩。


R
Rasmus Faber

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

要从 double 中获取指数和尾数,您可以将其转换为 IEEE 754 表示并提取如下所示的位:

long bits = Double.doubleToLongBits(3.25);

boolean isNegative = (bits & 0x8000000000000000L) != 0; 
long exponent      = (bits & 0x7ff0000000000000L) >> 52;
long mantissa      =  bits & 0x000fffffffffffffL;

尾数的第一位是不是隐式设置为1,所以尾数应该是(bits & 0x000fffffffffffffL) | 0x00100000000000000L?
Rasmus 它不是 ryt 输出输出:指数 0 和尾数 2814749767106560 如果你选择 urs agnul,尾数为 0
以 4 票赞成打破:) 虽然我看到代码试图在其关节处拆开双值,但代码似乎没有输出正确的值。
@agnul:我认为“尾数”通常仅指位的值。您可以通过(有时)添加 1 位将其转换为有效数字。但根据维基百科,尾数这个词现在已被弃用,取而代之的是“分数”。
Q
QED

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

float fp = ip % 1.0f;

O
OnePunchMan

主要逻辑您必须首先找到小数点后有多少位。此代码适用于最多 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);

伙计,对于一个简单的问题,这是一个极其复杂的答案。您是否看过已接受的答案?
现在投反对票的人(不是我顺便说一句)应该解释为什么会有反对票。这不好。但是我们所有人都在某个时候得了 1 分。
@Gray问题是将3.25分隔为'3'和'25',并且接受的答案永远不会给出'25',它总是会给出'2599999999'
@Gray 我知道谁投了反对票,这是一个名叫 Eji(老用户)的人,嘲笑我在此博客中发布的每一条评论、答案和问题。最后向版主投诉。
如果您希望小数部分为整数,此答案非常有用
S
Stephan

IEEE 双浮点数的尾数和指数是这样的值

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

如果尾数的形式为 0.101010101_base 2(即其最高位移动到二进制点之后)并且指数针对偏差进行了调整。

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

但是,您要求的数字是数字的整数部分和小数部分,可以使用

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

尽管您可能希望以不同的方式处理负数 (floor(-3.5) == -4.0),具体取决于您想要这两个部分的原因。

我强烈建议您不要称这些尾数和指数。


S
Stephen Darlington

[编辑:问题最初询问如何获得尾数和指数。]

其中 n 是获得真实尾数/指数的数字:

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

或者,要获得您正在寻找的答案:

exponent = int(n)
mantissa = n - exponent

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


r
roybraym

如果您的号码是 2.39999999999999,该怎么办。我想你想得到确切的十进制值。然后使用 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);

R
Roland Illig

由于 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>

只需尝试我示例中的所有数字。 fmt:formatNumber 对其参数进行四舍五入,这在本例中是不需要的。
b
benofben

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

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

@justshams 使用 Math.abs 怎么样?
u
user1817835

接受的答案不适用于 -0 和 -1.0 之间的负数。同时将小数部分设为负数。

例如:对于数字 -0,35

返回

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

如果您正在使用 GPS 坐标,则最好将整数部分的符号作为结果:

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

这些数字用于例如 GPS 坐标,其中纬度或经度位置的符号很重要

提议代码:

    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

S
Stephan

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

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

一些例子:

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

或者,可以使用 / 运算符:

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

参考:

Java 8:Math.floorDiv(int,int)

Java 8:Math.floorDiv(long,long)


E
Endery

我会使用 BigDecimal 作为解决方案。像这样:

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

s
slfan
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);
    }
}

此答案已被标记为低质量。如果它回答了问题,请考虑添加一些文本来解释它是如何工作的。
O
Omar Elashry

好的,这可能为时已晚,但我认为最好和更准确的方法是使用 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

如果你有一个双精度,它有浮点不精确。将其转换为 BigDecimal 不会神奇地恢复其精度。
@Taschi 我认为问题在于将 int 和小数部分分开,而不是恢复其精度!
奥马尔,你特别谈到你的方法“更准确”,我认为这不是真的。你的回答是完全可以接受的,但这个措辞对我来说似乎有误导性,这就是我评论它的原因。
@Taschi,我说,因为在许多答案中,当您获得输出时,您会失去价值,例如 input (5.03) output int = 5 , fractional = 0.0299999 ,我们正在谈论输入和输出,您投入价值并取回您的价值而不会损失 0.001%!而且这个准确,不会误导!
是的。当您首先将某些内容存储为双精度时,您会失去精度。转换为 BigDecimal 时的舍入也会丢失精度。这两种精度损失可能会相互抵消,但这并不能“恢复”精度,因为恢复精度在数学上是不可能的。你不能凭空提取信息。
w
w__
// 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

M
Michael Myers
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);
    }
}

这仅在数字恰好有 4 个小数位时才有效。不然。