Wie erhalte ich in JSP / Java ganze und gebrochene Teile von double?


104

Wie erhalte ich in JSP / Java ganze und gebrochene Teile von double? Wenn der Wert 3,25 ist, dann möchte ich bekommen fractional =.25,whole = 3

Wie können wir das in Java machen?


4
Sie scheinen eine ungenaue Vorstellung davon zu haben, was Mantisse und Exponent sind. Sie sind nicht nur "ganzer Teil" und "gebrochener Teil". Siehe en.wikipedia.org/wiki/Floating_point
Jon Skeet

Eigentlich habe ich ungefähr 5 Beiträge gelesen, bevor ich zu 'hey .. das wird kein Exponent genannt' gehe. Mein Gehirn warf die Wörter aus und fing an, das Problem zu lösen. Schlechte Gewohnheiten beim Lesen von Programmiermaterial haben mir gegeben :)
Gishu

1
Bitte formulieren Sie auch die Frage OP .. unter anderem aus Gründen der Nachwelt neu.
Gishu

1
Klingt verdächtig nach einem Hausaufgabenproblem.
Brian Knoblauch

Ohh ich sehe. Ich habe mich schon gefragt, wie er so seltsame Ergebnisse erzielt
Johannes Schaub - litb

Antworten:


102

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);

Ausgänge:

Integer part = 2
Fractional part = 0.2999999999999998

61
Tatsächlich ist diese Seite der erste Treffer bei einer Google-Suche nach "Holen Sie sich einen Bruchteil und einen ganzen Teil aus Double Java heraus" =)
Chris

12
Tatsächlich ist diese Antwort falsch, denn Werte, die größer als lang sind, können im Bruchteil große Zahlen ergeben. Die Antwort von Dan Vinton unten ist genauso einfach und liefert immer das richtige Ergebnis.
Arberg

2
Das ist also eigentlich nicht korrekt, wie Sie in der Ausgabe sehen können. Die Eingabe ist ein Bruchteil von 3 und die Ausgabe ist 29999999 ... die Verwendung von BigDecimal anstelle von Double reicht jedoch aus
Alex

2
@Alex Nein, die Eingabe ist eine Zahl, die sehr nahe kommt 2.3, aber sicherlich nicht 2.3. Und an der Ausgabe ist nichts auszusetzen, es sei denn, Sie möchten mehr als 10 gültige Ziffern. Alles, was Sie brauchen, ist eine Rundung in jeder Ausgabe (z. B. Format %.9f), die normalerweise weniger schmerzhaft ist als BigDecimal. Das einzige Problem hierbei ist der Überlauf.
Maaartinus

1
Die Konvertierung von double in int ist fast immer eine schlechte Idee. Denn zB für (long)1.0e100dich bekommst du 0. In vielen Fällen brauchst du den doppelten Wert einfach "bodenständig", für den es gibt floor(). Wenn Sie sowohl Integral- als auch Bruchteile verwenden möchten, verwenden Sie diese modf(). Das ist wirklich eine schlechte Antwort.
Mojuba

155
double value = 3.25;
double fractionalPart = value % 1;
double integralPart = value - fractionalPart;

12
Warum wird das abgelehnt? Funktioniert gut und funktioniert mit meiner Bearbeitung auch mit negativen Werten.
HRJ

Der ganzzahlige Teil könnte => long longPart = (long) 3.25 sein
jdurango

2
Funktioniert nicht für neg. Werte. Dh -3,25% 1 = 0,75 nicht 0,25. IntegralPart ist also -3,25 - 0,75 = -4.
WindRider

2
@WindRider, ich habe nach Negativen gesucht .. und es funktioniert .. aber bei Dezimalstellen, deren Anzahl gering ist, wird es einen kleinen Fehler geben. Ex. für -03.0025 gibt es -0.0024999999999999467 und -3.0 zurück
justshams

5
Die Verwirrung besteht darin, dass einige Sprachen wie Python %modulo ( -3.25 % 1 == 0.75) und andere wie Java, Fortran, C und C ++ %den Rest ( -3.25 % 1 == -0.25) bedeuten . WindRider hat es aus Gründen der Zweckmäßigkeit möglicherweise in eine Python-REPL eingegeben, aber diese Antwort ist irreführend, da es sich bei dieser Frage um die JVM handelt.
Jim Pivarski

24

Da diese 1-jährige Frage von jemandem aufgeworfen wurde, der das Thema der Frage korrigiert hat, und diese Frage mit einem Tag versehen jspist und hier niemand eine JSP-gezielte Antwort geben konnte, ist hier mein JSP-gezielter Beitrag.

Verwenden Sie JSTL (lassen Sie einfach jstl-1.2.jar ein /WEB-INF/lib) fmt taglib. Es gibt ein <fmt:formatNumber>Tag, das mit Hilfe von maxFractionDigitsund maxIntegerDigitsAttributen genau das macht, was Sie wollen und auf ganz einfache Weise .

Hier ist eine SSCCE , kopiere sie einfach und führe sie aus.

<%@ 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>

Ausgabe:

Ganzes: 3

Bruchteil: 0,25

Das ist es. Sie müssen es nicht mit Hilfe von Java-Rohcode massieren.


8

Die ursprüngliche Frage bezog sich eher auf den Exponenten und die Mantisse als auf den Bruchteil und den ganzen Teil.

Um den Exponenten und die Mantisse aus einem Doppel zu erhalten, können Sie sie in die IEEE 754- Darstellung konvertieren und die Bits wie folgt extrahieren:

long bits = Double.doubleToLongBits(3.25);

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

Ist nicht das erste Bit der mantinssa implizit auf 1 gesetzt, so sollte die Mantisse sein (Bits & 0x000fffffffffffffL) | 0x0010000000000000L?
Agnul

Rasmus es war keine ryt Ausgabe Ausgabe: Exponent 0 und Mantisse 2814749767106560 und wenn Sie unsere Agnul wählen, ist die Mantisse 0
Vinayak Bevinakatti

Mit 4 Stimmen gebrochen :) Obwohl ich sehe, was der Code mit dem Zerlegen von Doppelwerten an seinen Gelenken zu tun versucht, scheint der Code nicht die richtigen Werte auszugeben.
Gishu

@agnul: Ich denke, "Mantisse" bezieht sich normalerweise nur auf den Wert der Bits. Sie können dies einfach in den Signifikanten konvertieren, indem Sie (manchmal) ein 1-Bit voranstellen. Aber laut Wikipedia ist das Wort Mantisse jetzt zugunsten von "Bruch" veraltet.
Rasmus Faber

5

Hauptlogik Sie müssen zuerst herausfinden, wie viele Stellen nach dem Dezimalpunkt stehen.
Dieser Code funktioniert für eine beliebige Zahl mit bis zu 16 Ziffern. Wenn Sie BigDecimal verwenden, können Sie es nur mit bis zu 18 Stellen ausführen. Setzen Sie den Eingabewert (Ihre Nummer) in die Variable "num", hier als Beispiel habe ich ihn fest codiert.

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);

Alter, das ist eine äußerst komplizierte Antwort auf ein einfaches Problem. Haben Sie sich die akzeptierte Antwort angesehen?
Grau

1
Nun hätte die Person, die die Abwahl durchgeführt hat (übrigens nicht ich), erklären müssen, warum es eine Abwahl gab. Das ist nicht gut. Aber wir alle hatten irgendwann eine Punktzahl von 1.
Grau

2
@Gray die Frage war, 3.25 als '3' und '25' zu trennen, und die akzeptierte Antwort wird niemals '25' geben, es wird immer '2599999999' geben
OnePunchMan

@Gray Ich weiß, wer es abgelehnt hat, es war ein Typ namens Eji (alter Benutzer), der sich über jeden meiner Kommentare, Antworten und Fragen lustig machte, die ich in diesem Blog poste. Schließlich beschwere ich mich beim Moderator.
OnePunchMan

2
Diese Antwort ist sehr nützlich, wenn Sie den Bruchteil als Ganzzahl wollen
Guilherme Campos Hazan

5

Die Mantisse und der Exponent einer IEEE-Doppelgleitkommazahl sind die Werte, die

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

wenn die Mantisse die Form 0.101010101_base 2 hat (dh ihr signifikantestes Bit wird verschoben, um nach dem Binärpunkt zu liegen) und der Exponent auf Vorspannung eingestellt ist.

Seit 1.6 bietet java.lang.Math auch eine direkte Methode zum Abrufen des unverzerrten Exponenten (getExponent (double) genannt).

Die Zahlen, nach denen Sie fragen, sind jedoch die integralen und gebrochenen Teile der Zahl, die mit erhalten werden können

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

Möglicherweise möchten Sie negative Zahlen jedoch unterschiedlich behandeln (floor(-3.5) == -4.0), je nachdem, warum Sie die beiden Teile möchten.

Ich würde dringend empfehlen, diese Mantisse und diesen Exponenten nicht zu nennen.


4

Ich weiß nicht, ob das schneller ist, aber ich benutze

float fp = ip % 1.0f;

3

[Bearbeiten: Die Frage fragte ursprünglich, wie man die Mantisse und den Exponenten erhält.]

Wobei n die Zahl ist, um die reale Mantisse / den Exponenten zu erhalten:

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

Oder um die Antwort zu erhalten, nach der Sie gesucht haben:

exponent = int(n)
mantissa = n - exponent

Diese sind nicht genau Java, sollten aber einfach zu konvertieren sein.


3

Der ganzzahlige Teil ergibt sich aus dem einfachen Casting und für die Teilung von Teilstrings:

double value = 123.004567890

int integerPart = (int) value; // 123

int fractionPart = 
  Integer.valueOf(String.valueOf(value)
      .split(".")[1]); // 004567890

/**
* To control zeroes omitted from start after parsing.
*/
int decimals =
  String.valueOf(value)
      .split(".")[1].length(); // 9

1

Was ist, wenn Ihre Nummer 2.39999999999999 lautet? Ich nehme an, Sie möchten den genauen Dezimalwert erhalten. Verwenden Sie dann 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);

0

Da das fmt:formatNumberTag nicht immer das richtige Ergebnis liefert, gibt es einen weiteren Ansatz nur für JSP: Es formatiert nur die Zahl als Zeichenfolge und führt den Rest der Berechnung für die Zeichenfolge durch, da dies einfacher ist und keinen weiteren Gleitkommawert beinhaltet Arithmetik.

<%@ 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>

Probieren Sie einfach alle Zahlen aus meinem Beispiel aus. fmt:formatNumberrundet sein Argument ab, das in diesem Fall nicht erwünscht ist.
Roland Illig

0

Viele dieser Antworten weisen schreckliche Rundungsfehler auf, weil sie Zahlen von einem Typ zum anderen übertragen. Wie wäre es mit:

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

@justshams Was ist mit Math.abs?
Stephan

0

Die akzeptierte Antwort funktioniert nicht gut für negative Zahlen zwischen -0 und -1,0. Geben Sie auch den Bruchteil negativ an.

Zum Beispiel: Für die Nummer -0,35

kehrt zurück

Ganzzahliger Teil = 0 Bruchteil = -0,35

Wenn Sie mit GPS-Koordinaten arbeiten, ist es besser, ein Ergebnis mit dem Signal auf dem ganzzahligen Teil zu erhalten als:

Ganzzahliger Teil = -0 Bruchteil = 0,35

Diese Zahlen werden beispielsweise für GPS-Koordinaten verwendet, wobei das Signal für die Lat- oder Long-Position wichtig ist

Code vorschlagen:

    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));

Ausgabe:

Integer part = -0
Fractional part = 0,3500

0

Seit Java 8 können Sie verwenden Math.floorDiv.

Es wird der größte intWert (der der positiven Unendlichkeit am nächsten kommt) zurückgegeben, der kleiner oder gleich dem algebraischen Quotienten ist.

Einige Beispiele:

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

Alternativ kann der /Operator verwendet werden:

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

Verweise:


0

Ich würde BigDecimal für die Lösung verwenden. So was:

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

0
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);
    }
}

Diese Antwort wurde als minderwertig gekennzeichnet. Wenn die Frage beantwortet wird, sollten Sie ein wenig Text hinzufügen, um zu erklären, wie es funktioniert.
lmo

0
// 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

0

OK, das ist vielleicht spät, aber ich denke, der beste und genauere Ansatz ist die Verwendung von 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

Wenn Sie ein Double haben, hat es Float-Ungenauigkeit. Durch die Konvertierung in ein BigDecimal wird die Genauigkeit nicht auf magische Weise wiederhergestellt.
Taschi

@Taschi Ich denke, die Frage ist die Trennung des int und des gebrochenen Teils, nicht die Wiederherstellung seiner Präzision!
Omar Elashry

Omar, Sie haben speziell davon gesprochen, dass Ihr Ansatz "genauer" ist, was meiner Meinung nach einfach nicht stimmt. Ihre Antwort ist völlig akzeptabel, aber dieser Wortlaut scheint mir irreführend, weshalb ich ihn kommentiert habe.
Taschi

@Taschi, ich sagte, weil Sie in vielen Antworten an Wert verlieren, wenn Sie die Ausgabe erhalten, z. B. wenn input (5.03) output int = 5 , fractional = 0.0299999wir über Ein- und Ausgaben sprechen, setzen Sie Wert und erhalten Sie Ihren Wert zurück, ohne 0,001% davon zu verlieren! und das genau, nicht irreführend!
Omar Elashry

Ja. Sie verlieren an Präzision, wenn Sie etwas als Double speichern. Das Runden beim Konvertieren in ein BigDecimal verliert ebenfalls an Genauigkeit. Diese beiden Genauigkeitsverluste können sich gegenseitig aufheben, aber dies "stellt" die Genauigkeit nicht wieder her, da die Wiederherstellung der Genauigkeit mathematisch unmöglich ist. Sie können keine Informationen aus der Luft ziehen.
Taschi

-2
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);
    }
}

Dies funktioniert nur, wenn die Zahl genau 4 Dezimalstellen hat. Nicht anders.
Marquis von Lorne
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.