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
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 =2Fractional part =0.2999999999999998
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;
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.
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:
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.
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.
Der ganzzahlige Teil ergibt sich aus dem einfachen Casting und für die Teilung von Teilstrings:
double value =123.004567890int integerPart =(int) value;// 123int 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
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.
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));
Es wird der größte intWert (der der positiven Unendlichkeit am nächsten kommt) zurückgegeben, der kleiner oder gleich dem algebraischen Quotienten ist.
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();
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 numberdouble d =3.025;// transfer the number to stringDecimalFormat df =newDecimalFormat();
df.setDecimalSeparatorAlwaysShown(false);String format = df.format(d);// split the number into two fragmentsint dotIndex = format.indexOf(".");int iPart =Integer.parseInt(format.substring(0, dotIndex));// output: 3double fPart =Double.parseDouble(format.substring(dotIndex));// output: 0.025
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.
Antworten:
http://www.java2s.com/Code/Java/Data-Type/Obtainingtheintegerandfractionalparts.htm
Ausgänge:
quelle
2.3
, aber sicherlich nicht2.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 alsBigDecimal
. Das einzige Problem hierbei ist der Überlauf.(long)1.0e100
dich bekommst du 0. In vielen Fällen brauchst du den doppelten Wert einfach "bodenständig", für den es gibtfloor()
. Wenn Sie sowohl Integral- als auch Bruchteile verwenden möchten, verwenden Sie diesemodf()
. Das ist wirklich eine schlechte Antwort.quelle
%
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.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 vonmaxFractionDigits
undmaxIntegerDigits
Attributen genau das macht, was Sie wollen und auf ganz einfache Weise .Hier ist eine SSCCE , kopiere sie einfach und führe sie aus.
Ausgabe:
Das ist es. Sie müssen es nicht mit Hilfe von Java-Rohcode massieren.
quelle
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:
quelle
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.
quelle
Die Mantisse und der Exponent einer IEEE-Doppelgleitkommazahl sind die Werte, die
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
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.
quelle
Ich weiß nicht, ob das schneller ist, aber ich benutze
quelle
[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:
Oder um die Antwort zu erhalten, nach der Sie gesucht haben:
Diese sind nicht genau Java, sollten aber einfach zu konvertieren sein.
quelle
Der ganzzahlige Teil ergibt sich aus dem einfachen Casting und für die Teilung von Teilstrings:
quelle
Was ist, wenn Ihre Nummer 2.39999999999999 lautet? Ich nehme an, Sie möchten den genauen Dezimalwert erhalten. Verwenden Sie dann BigDecimal:
quelle
Da das
fmt:formatNumber
Tag 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.quelle
fmt:formatNumber
rundet sein Argument ab, das in diesem Fall nicht erwünscht ist.Viele dieser Antworten weisen schreckliche Rundungsfehler auf, weil sie Zahlen von einem Typ zum anderen übertragen. Wie wäre es mit:
quelle
Math.abs
?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:
Ausgabe:
quelle
Seit Java 8 können Sie verwenden
Math.floorDiv
.Es wird der größte
int
Wert (der der positiven Unendlichkeit am nächsten kommt) zurückgegeben, der kleiner oder gleich dem algebraischen Quotienten ist.Einige Beispiele:
Alternativ kann der
/
Operator verwendet werden:Verweise:
quelle
Ich würde BigDecimal für die Lösung verwenden. So was:
quelle
quelle
quelle
OK, das ist vielleicht spät, aber ich denke, der beste und genauere Ansatz ist die Verwendung von BigDecimal
quelle
input (5.03)
output int = 5 , fractional = 0.0299999
wir ü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!quelle