Comment obtenir des parties entières et fractionnaires à partir de doubles dans JSP / Java?
104
Comment obtenir des parties entières et fractionnaires à partir de doubles dans JSP / Java? Si la valeur est de 3,25, je veux obtenirfractional =.25 ,whole = 3
Vous semblez avoir une idée inexacte de ce que sont la mantisse et l'exposant. Ils ne sont pas simplement «partie entière» et «partie fractionnaire». Voir en.wikipedia.org/wiki/Floating_point
Jon Skeet
En fait, j'ai lu environ 5 articles avant de dire «hé… ça ne s'appelle pas un exposant». Mon cerveau a jeté les mots et a commencé à résoudre le problème ... les mauvaises habitudes de lecture de programmes m'ont donné :)
Gishu
1
Veuillez également reformuler la question OP .. pour la postérité entre autres raisons.
Gishu
1
Cela ressemble étrangement à un problème de devoirs.
Brian Knoblauch
Oh je vois. Je me suis déjà demandé comment il obtient des résultats si étranges
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);
Les sorties:
Integer part =2Fractional part =0.2999999999999998
En fait, cette page est le premier résultat d'une recherche google pour "obtenir une partie fractionnaire et entière de double java" =)
Chris
12
En fait, cette réponse est incorrecte, car les valeurs supérieures à long peuvent représenter, cela donnera des nombres énormes dans la partie fractionnaire. La réponse de Dan Vinton ci-dessous est tout aussi simple et renvoie toujours le résultat correct.
arberg
2
donc en fait, ce n'est pas correct, comme vous pouvez le voir dans la sortie. l'entrée est une fraction de 3 et la sortie est 29999999 ... l'utilisation de BigDecimal au lieu de Double fera l'affaire
Alex
2
@Alex Non, l'entrée est un nombre très proche 2.3, mais sûrement pas 2.3. Et il n'y a rien de mal avec la sortie, sauf si vous voulez beaucoup plus de 10 chiffres valides. Tout ce dont vous avez besoin est un arrondi dans chaque sortie (par exemple, le format %.9f), ce qui est généralement moins pénible que BigDecimal. Le seul problème ici est le débordement.
maaartinus
1
La conversion de double en int est presque toujours une mauvaise idée. Parce que par exemple pour (long)1.0e100vous obtiendrez 0. La plupart du temps, vous avez besoin de la valeur double simplement "floored" pour laquelle il y a floor(). Si vous souhaitez utiliser à la fois des parties intégrales et fractionnaires modf(). Vraiment, c'est une mauvaise réponse.
mojuba
155
double value =3.25;double fractionalPart = value %1;double integralPart = value - fractionalPart;
Pourquoi ce vote est-il défavorable? Fonctionne bien, et avec ma modification fonctionnera également avec des valeurs négatives.
HRJ
La partie entière pourrait être => long longPart = (long) 3.25
jdurango
2
Ne fonctionnera pas pour neg. valeurs. Ie -3,25% 1 = 0,75 et non 0,25. Donc, intégralPart sera -3,25 - 0,75 = -4.
WindRider
2
@WindRider, j'ai vérifié le négatif .. et ses travaux .. cependant pour les décimales qui sont en petit nombre, il y aura une légère erreur. Ex. pour -03,0025, il renvoie -0,0024999999999999467 et -3,0
justshams
5
La confusion ici est due au fait que certains langages, tels que Python, %signifient modulo ( -3.25 % 1 == 0.75) et d'autres, tels que Java, Fortran, C et C ++, utilisent %pour signifier reste ( -3.25 % 1 == -0.25). WindRider l'a peut-être tapé dans une REPL Python pour des raisons de commodité, mais cette réponse est trompeuse car cette question concerne la JVM.
Jim Pivarski
24
Depuis que cette question d'un an a été soulevée par quelqu'un qui a corrigé le sujet de la question, et cette question a été identifiée jsp , et que personne ici n'a été en mesure de donner une réponse ciblée JSP, voici ma contribution ciblée sur JSP.
Utilisez JSTL (déposez simplement jstl-1.2.jar dans /WEB-INF/lib) fmt taglib. Il y a une <fmt:formatNumber>balise qui fait exactement ce que vous voulez et d'une manière assez simple avec l'aide de maxFractionDigitsetmaxIntegerDigits attributs.
<%@ 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>
Production:
Entier: 3
Fraction: 0,25
C'est tout. Pas besoin de le masser avec l'aide de code Java brut.
Le premier bit de la mantins n'est-il pas implicitement mis à 1, donc la mantisse devrait être (bits & 0x000fffffffffffffL) | 0x0010000000000000L?
agnul
Rasmus ce n'était pas une sortie ryt Sortie: exposant 0 et mantisse 2814749767106560 et si vous choisissez urs agnul, la mantisse est 0
Vinayak Bevinakatti
Cassé avec 4 votes positifs :) Bien que je vois ce que le code essaie de faire en supprimant la double valeur à ses articulations, le code ne semble pas afficher les bonnes valeurs.
Gishu
@agnul: Je pense que "mantisse" se réfère généralement à la valeur des bits. Vous pouvez simplement le convertir en significand en ajoutant (parfois) un bit au début. Mais selon Wikipedia, le mot mantisse est désormais obsolète au profit de «fraction».
Rasmus Faber
5
Logique principale, vous devez d'abord trouver le nombre de chiffres après la virgule décimale.
Ce code fonctionne pour n'importe quel nombre jusqu'à 16 chiffres. Si vous utilisez BigDecimal, vous pouvez l'exécuter uniquement pour jusqu'à 18 chiffres. mettez la valeur d'entrée (votre nombre) à la variable "num", ici à titre d'exemple je l'ai codée en dur.
Mec, c'est une réponse extrêmement compliquée à un problème simple. Avez-vous jeté un œil à la réponse acceptée?
Gris
1
Maintenant, la personne qui a voté contre (pas moi d'ailleurs) aurait dû expliquer pourquoi il y avait eu un vote contre. Ce n'est pas bon. Mais nous avons tous eu un score de 1 à un moment ou à un autre.
Gris
2
@Gray, la question était de séparer 3,25 par '3' et '25', et la réponse acceptée ne donnera jamais '25', elle donnera toujours '2599999999'
OnePunchMan
@Gray Je sais qui a voté contre, c'était un gars nommé Eji (ancien utilisateur) se moquant de chacun de mes commentaires, réponses et questions que je publie dans ce blog. Enfin, je me plains au modérateur.
OnePunchMan
2
Cette réponse est très utile si vous voulez la partie fractionnaire sous forme d'entier
Guilherme Campos Hazan
5
La mantisse et l'exposant d'un nombre à virgule flottante double IEEE sont les valeurs telles que
value = sign *(1+ mantissa)* pow(2, exponent)
si la mantisse est de la forme 0.101010101_base 2 (c'est-à-dire que son bit le plus significatif est décalé pour être après le point binaire) et que l'exposant est ajusté pour la polarisation.
Depuis 1.6, java.lang.Math fournit également une méthode directe pour obtenir l'exposant non biaisé (appelé getExponent (double))
Cependant, les nombres que vous demandez sont les parties intégrales et fractionnaires du nombre, qui peuvent être obtenues en utilisant
integral =Math.floor(x)
fractional = x -Math.floor(x)
bien que vous souhaitiez peut-être traiter les nombres négatifs différemment (floor(-3.5) == -4.0) , selon la raison pour laquelle vous voulez les deux parties.
Je vous suggère fortement de ne pas appeler ces mantisses et exposants.
La partie entière est obtenue à partir de la conversion simple et pour le fractionnement de chaîne fractionnaire:
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
Étant donné que la fmt:formatNumberbalise ne donne pas toujours le résultat correct, voici une autre approche uniquement JSP: elle formate simplement le nombre sous forme de chaîne et effectue le reste du calcul sur la chaîne, car cela est plus facile et n'implique pas davantage de virgule flottante arithmétique.
La réponse acceptée ne fonctionne pas bien pour les nombres négatifs entre -0 et -1.0 Donnez également la partie fractionnaire négative.
Par exemple: pour le numéro -0,35
Retour
Partie entière = 0 Partie fractionnaire = -0,35
Si vous travaillez avec des coordonnées GPS, il est préférable d'avoir un résultat avec le signe sur la partie entière comme:
Partie entière = -0 Partie fractionnaire = 0,35
Ces nombres sont utilisés par exemple pour les coordonnées GPS, où sont importants le signe pour la position Lat ou Long
Proposer un code:
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));
J'utiliserais BigDecimal pour la solution. Comme ça:
double value =3.25;BigDecimal wholeValue =BigDecimal.valueOf(value).setScale(0,BigDecimal.ROUND_DOWN);double fractionalValue = value - wholeValue.doubleValue();
Cette réponse a été signalée comme étant de mauvaise qualité. S'il répond à la question, pensez à ajouter un peu de texte pour expliquer son fonctionnement.
lmo le
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
Si vous avez un double, il a une imprécision de flotteur. Le convertir en BigDecimal ne restaure pas comme par magie sa précision.
Taschi
@Taschi je pense que la question est de séparer l'int et la partie fractionnaire, pas de restaurer sa précision!
Omar Elashry le
Omar, vous avez spécifiquement dit que votre approche était «plus précise», ce qui, à mon avis, n'est tout simplement pas vrai. Votre réponse est tout à fait acceptable, mais cette formulation me semble trompeuse, c'est pourquoi je l'ai commentée.
Taschi
@Taschi, j'ai dit cela parce que dans de nombreuses réponses, vous perdez de la valeur lorsque vous obtenez la sortie, par exemple input (5.03)output int = 5 , fractional = 0.0299999, nous parlons d'entrées et de sorties, vous mettez de la valeur et récupérez votre valeur sans en perdre 0,001%! et ce précis, pas trompeur!
Omar Elashry
Oui. Vous perdez de la précision lorsque vous stockez quelque chose comme un double en premier lieu. L'arrondi lors de la conversion en BigDecimal perd également de la précision. Ces deux pertes de précision peuvent s'annuler, mais cela ne "restaure" pas la précision, car la restauration de la précision est mathématiquement impossible. Vous ne pouvez pas extraire des informations de rien.
Réponses:
http://www.java2s.com/Code/Java/Data-Type/Obtainingtheintegerandfractionalparts.htm
Les sorties:
la source
2.3
, mais sûrement pas2.3
. Et il n'y a rien de mal avec la sortie, sauf si vous voulez beaucoup plus de 10 chiffres valides. Tout ce dont vous avez besoin est un arrondi dans chaque sortie (par exemple, le format%.9f
), ce qui est généralement moins pénible queBigDecimal
. Le seul problème ici est le débordement.(long)1.0e100
vous obtiendrez 0. La plupart du temps, vous avez besoin de la valeur double simplement "floored" pour laquelle il y afloor()
. Si vous souhaitez utiliser à la fois des parties intégrales et fractionnairesmodf()
. Vraiment, c'est une mauvaise réponse.la source
%
signifient modulo (-3.25 % 1 == 0.75
) et d'autres, tels que Java, Fortran, C et C ++, utilisent%
pour signifier reste (-3.25 % 1 == -0.25
). WindRider l'a peut-être tapé dans une REPL Python pour des raisons de commodité, mais cette réponse est trompeuse car cette question concerne la JVM.Depuis que cette question d'un an a été soulevée par quelqu'un qui a corrigé le sujet de la question, et cette question a été identifiée jsp , et que personne ici n'a été en mesure de donner une réponse ciblée JSP, voici ma contribution ciblée sur JSP.
Utilisez JSTL (déposez simplement jstl-1.2.jar dans
/WEB-INF/lib
) fmt taglib. Il y a une<fmt:formatNumber>
balise qui fait exactement ce que vous voulez et d'une manière assez simple avec l'aide demaxFractionDigits
etmaxIntegerDigits
attributs.Voici un SSCCE , copiez-le , collez-le et exécutez-le.
Production:
C'est tout. Pas besoin de le masser avec l'aide de code Java brut.
la source
La question originale demandait l'exposant et la mantisse, plutôt que la partie fractionnaire et entière.
Pour obtenir l'exposant et la mantisse d'un double, vous pouvez le convertir en représentation IEEE 754 et extraire les bits comme ceci:
la source
Logique principale, vous devez d'abord trouver le nombre de chiffres après la virgule décimale.
Ce code fonctionne pour n'importe quel nombre jusqu'à 16 chiffres. Si vous utilisez BigDecimal, vous pouvez l'exécuter uniquement pour jusqu'à 18 chiffres. mettez la valeur d'entrée (votre nombre) à la variable "num", ici à titre d'exemple je l'ai codée en dur.
la source
La mantisse et l'exposant d'un nombre à virgule flottante double IEEE sont les valeurs telles que
si la mantisse est de la forme 0.101010101_base 2 (c'est-à-dire que son bit le plus significatif est décalé pour être après le point binaire) et que l'exposant est ajusté pour la polarisation.
Depuis 1.6, java.lang.Math fournit également une méthode directe pour obtenir l'exposant non biaisé (appelé getExponent (double))
Cependant, les nombres que vous demandez sont les parties intégrales et fractionnaires du nombre, qui peuvent être obtenues en utilisant
bien que vous souhaitiez peut-être traiter les nombres négatifs différemment
(floor(-3.5) == -4.0)
, selon la raison pour laquelle vous voulez les deux parties.Je vous suggère fortement de ne pas appeler ces mantisses et exposants.
la source
Je ne sais pas si c'est plus rapide mais j'utilise
la source
[Modifier: La question demandait à l'origine comment obtenir la mantisse et l'exposant.]
Où n est le nombre pour obtenir la vraie mantisse / exposant:
Ou, pour obtenir la réponse que vous recherchiez:
Ce ne sont pas exactement Java, mais devraient être faciles à convertir.
la source
La partie entière est obtenue à partir de la conversion simple et pour le fractionnement de chaîne fractionnaire:
la source
Et si votre numéro est 2,39999999999999. Je suppose que vous voulez obtenir la valeur décimale exacte. Ensuite, utilisez BigDecimal:
la source
Étant donné que la
fmt:formatNumber
balise ne donne pas toujours le résultat correct, voici une autre approche uniquement JSP: elle formate simplement le nombre sous forme de chaîne et effectue le reste du calcul sur la chaîne, car cela est plus facile et n'implique pas davantage de virgule flottante arithmétique.la source
fmt:formatNumber
arrondit son argument, ce qui n'est pas voulu dans ce cas.Beaucoup de ces réponses comportent d'horribles erreurs d'arrondi, car elles transposent des nombres d'un type à un autre. Que diriez-vous:
la source
Math.abs
?La réponse acceptée ne fonctionne pas bien pour les nombres négatifs entre -0 et -1.0 Donnez également la partie fractionnaire négative.
Par exemple: pour le numéro -0,35
Retour
Partie entière = 0 Partie fractionnaire = -0,35
Si vous travaillez avec des coordonnées GPS, il est préférable d'avoir un résultat avec le signe sur la partie entière comme:
Partie entière = -0 Partie fractionnaire = 0,35
Ces nombres sont utilisés par exemple pour les coordonnées GPS, où sont importants le signe pour la position Lat ou Long
Proposer un code:
Production:
la source
Depuis Java 8, vous pouvez utiliser
Math.floorDiv
.Il renvoie le plus grand (le plus proche de l'infini positif)
int
inférieure ou égale au quotient algébrique.Quelques exemples:
Alternativement, l'
/
opérateur peut être utilisé:Références:
la source
J'utiliserais BigDecimal pour la solution. Comme ça:
la source
la source
la source
OK, c'est peut-être tard, mais je pense que la meilleure approche et la plus précise consiste à utiliser BigDecimal
la source
input (5.03)
output int = 5 , fractional = 0.0299999
, nous parlons d'entrées et de sorties, vous mettez de la valeur et récupérez votre valeur sans en perdre 0,001%! et ce précis, pas trompeur!la source