Parece tener una idea inexacta de lo que son la mantisa y el exponente. No son solo "parte completa" y "parte fraccionaria". Ver en.wikipedia.org/wiki/Floating_point
Jon Skeet
De hecho, leí alrededor de 5 publicaciones antes de decir 'hey ... eso no se llama exponente'. Mi cerebro tiró las palabras y comenzó a resolver el problema ... malos hábitos que me ha dado leer cosas de programación :)
Gishu
1
También reformule la pregunta OP .. para la posteridad, entre otras razones.
Gishu
1
Suena sospechosamente a un problema de tarea.
Brian Knoblauch
Oh, ya veo. Ya me preguntaba cómo obtiene resultados tan extraños
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);
Salidas:
Integer part =2Fractional part =0.2999999999999998
En realidad, esta página es el primer resultado en una búsqueda de Google para "obtener parte fraccionada y completa de doble java" =)
Chris
12
En realidad, esta respuesta es incorrecta, ya que los valores más grandes que long pueden representar, dará números enormes en la parte fraccionaria. La respuesta de Dan Vinton a continuación es igual de simple y siempre devuelve el resultado correcto.
Arberg
2
así que, en realidad, esto no es correcto, como puede ver en el resultado. la entrada es una fracción de 3 y la salida es 29999999 ... usar BigDecimal en lugar de Double hará el truco sin embargo
Alex
2
@Alex No, la entrada es un número muy cercano 2.3, pero seguramente no 2.3. Y no hay nada de malo en la salida, a menos que desee mucho más de 10 dígitos válidos. Todo lo que necesita es algo de redondeo en cada salida (por ejemplo, formato %.9f) que generalmente es menos complicado que BigDecimal. El único problema aquí es el desbordamiento.
maaartinus
1
Convertir double en int es casi siempre una mala idea. Porque, por ejemplo, para (long)1.0e100obtendrá 0. Muchas veces necesita el valor doble simplemente "floored" para el que existe floor(). Si desea utilizar partes integrales y fraccionarias modf(). Realmente, esta es una mala respuesta.
mojuba
155
double value =3.25;double fractionalPart = value %1;double integralPart = value - fractionalPart;
¿Por qué se vota negativamente? Funciona bien y con mi edición funcionará también con valores negativos.
HRJ
La parte entera podría ser => long longPart = (long) 3.25
jdurango
2
No funcionará para neg. valores. Es decir, -3,25% 1 = 0,75 no 0,25. Entonces, integralPart será -3.25 - 0.75 = -4.
WindRider
2
@WindRider, verifiqué negativo ... y funciona ... sin embargo, para lugares decimales que son pequeños en número, habrá un pequeño error. Ex. para -03.0025 devuelve -0.0024999999999999467 y -3.0
justshams
5
La confusión aquí es porque algunos lenguajes, como Python, usan %para significar módulo ( -3.25 % 1 == 0.75) y otros, como Java, Fortran, C y C ++, usan %para significar resto ( -3.25 % 1 == -0.25). WindRider puede haberlo escrito en un REPL de Python por conveniencia, pero esa respuesta es engañosa porque esta pregunta es sobre la JVM.
Jim Pivarski
24
Dado que esta pregunta de 1 año fue lanzada por alguien que corrigió el asunto de la pregunta, y esta pregunta está etiquetada jsp, y nadie aquí pudo dar una respuesta dirigida a JSP, aquí está mi contribución dirigida a JSP.
Utilice JSTL (simplemente coloque jstl-1.2.jar en /WEB-INF/lib) fmt taglib. Hay una <fmt:formatNumber>etiqueta que hace exactamente lo que quieres y de una manera bastante fácil con la ayuda de maxFractionDigitsy maxIntegerDigitsatributos.
Aquí hay un SSCCE , simplemente cópielo, péguelo y ejecútelo.
<%@ 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>
Salida:
Entero: 3
Fracción: .25
Eso es. No es necesario masajearlo con la ayuda de código Java sin procesar.
¿No está el primer bit de mantinssa establecido implícitamente en 1, por lo que la mantisa debería ser (bits & 0x000fffffffffffffL) | 0x0010000000000000L?
agnul
Rasmus no era una salida ryt Salida: exponente 0 y mantisa 2814749767106560 y si elige urs agnul, la mantisa es 0
Vinayak Bevinakatti
Roto con 4 votos a favor :) Aunque veo lo que el código está tratando de hacer al desarmar el valor doble en sus uniones, el código no parece generar los valores correctos.
Gishu
@agnul: Creo que "mantisa" generalmente se refiere solo al valor de los bits. Puede convertir esto al significado (a veces) anteponiendo un 1 bit. Pero según Wikipedia, la palabra mantisa ahora está en desuso en favor de "fracción".
Rasmus Faber
5
Lógica principal: primero tienes que encontrar cuántos dígitos hay después del punto decimal.
Este código funciona para cualquier número de hasta 16 dígitos. Si usa BigDecimal, puede ejecutarlo solo para hasta 18 dígitos. ponga el valor de entrada (su número) a la variable "num", aquí como ejemplo lo he codificado.
Amigo, esta es una respuesta extremadamente complicada para un problema simple. ¿Echaste un vistazo a la respuesta aceptada?
Gray
1
Ahora, la persona que votó en contra (no yo por cierto), debería haber explicado por qué hubo una votación en contra. Eso no es bueno. Pero todos obtuvimos una puntuación de 1 en algún momento.
Gray
2
@Gray, la pregunta era separar 3.25 como '3' y '25', y la respuesta aceptada nunca dará '25', siempre dará '2599999999'
OnePunchMan
@ Gray, sé quién lo rechazó, era un tipo llamado Eji (antiguo usuario) que se burlaba de todos y cada uno de mis comentarios, respuestas y preguntas que publico en este blog. Finalmente me quejo con el moderador.
OnePunchMan
2
Esta respuesta es muy útil si desea que la parte fraccionaria sea un entero
Guilherme Campos Hazan
5
La mantisa y el exponente de un número de coma flotante doble IEEE son los valores tales que
value = sign *(1+ mantissa)* pow(2, exponent)
si la mantisa tiene la forma 0.101010101_base 2 (es decir, su bit más significativo se desplaza para estar después del punto binario) y el exponente se ajusta por sesgo.
Desde 1.6, java.lang.Math también proporciona un método directo para obtener el exponente insesgado (llamado getExponent (doble))
Sin embargo, los números que solicita son las partes integrales y fraccionarias del número, que se pueden obtener usando
integral =Math.floor(x)
fractional = x -Math.floor(x)
aunque es posible que desee tratar los números negativos de manera diferente (floor(-3.5) == -4.0) , dependiendo de por qué desea las dos partes.
Sugiero encarecidamente que no los llame mantisa y exponente.
La parte entera se obtiene de la fundición simple y para la división de cadenas fraccionarias:
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
Dado que la fmt:formatNumberetiqueta no siempre produce el resultado correcto, aquí hay otro enfoque solo de JSP: simplemente formatea el número como una cadena y hace el resto del cálculo en la cadena, ya que es más fácil y no implica más puntos flotantes aritmética.
La respuesta aceptada no funciona bien para números negativos entre -0 y -1.0 También dé la parte fraccionaria negativa.
Por ejemplo: para el número -0,35
devoluciones
Parte entera = 0 Parte fraccionaria = -0,35
Si está trabajando con coordenadas GPS, es mejor obtener un resultado con el signo en la parte entera como:
Parte entera = -0 Parte fraccionaria = 0.35
Estos números se utilizan, por ejemplo, para las coordenadas GPS, donde es importante el signo de la posición Lat o Long
Proponer código:
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));
Usaría BigDecimal para la solución. Me gusta esto:
double value =3.25;BigDecimal wholeValue =BigDecimal.valueOf(value).setScale(0,BigDecimal.ROUND_DOWN);double fractionalValue = value - wholeValue.doubleValue();
Esta respuesta se ha marcado como de baja calidad. Si responde la pregunta, considere agregar un poco de texto para explicar cómo funciona.
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
Si tiene un doble, tiene imprecisión de flotación. Convertirlo en un BigDecimal no restaurará mágicamente su precisión.
Taschi
@Taschi creo que la pregunta es sobre separar el int y la parte fraccionaria, ¡no sobre restaurar su precisión!
Omar Elashry
Omar, hablaste específicamente de que tu enfoque es "más preciso", lo que creo que no es cierto. Su respuesta es totalmente aceptable, pero esa redacción me parece engañosa, por eso la comenté.
Taschi
@Taschi, dije que debido a que en muchas respuestas pierdes valor cuando obtienes la salida, por ejemplo input (5.03)output int = 5 , fractional = 0.0299999, estamos hablando de entradas y salidas, ¡pones valor y recuperas tu valor sin perder el 0.001%! ¡Y esto es exacto, no engañoso!
Omar Elashry
si. Pierde precisión cuando almacena algo como doble en primer lugar. El redondeo al convertir a BigDecimal también pierde precisión. Esas dos pérdidas de precisión pueden anularse entre sí, pero eso no "restaura" la precisión, porque restaurar la precisión es matemáticamente imposible. No puedes sacar información de la nada.
Respuestas:
http://www.java2s.com/Code/Java/Data-Type/Obtainingtheintegerandfractionalparts.htm
Salidas:
fuente
2.3
, pero seguramente no2.3
. Y no hay nada de malo en la salida, a menos que desee mucho más de 10 dígitos válidos. Todo lo que necesita es algo de redondeo en cada salida (por ejemplo, formato%.9f
) que generalmente es menos complicado queBigDecimal
. El único problema aquí es el desbordamiento.(long)1.0e100
obtendrá 0. Muchas veces necesita el valor doble simplemente "floored" para el que existefloor()
. Si desea utilizar partes integrales y fraccionariasmodf()
. Realmente, esta es una mala respuesta.fuente
%
para significar módulo (-3.25 % 1 == 0.75
) y otros, como Java, Fortran, C y C ++, usan%
para significar resto (-3.25 % 1 == -0.25
). WindRider puede haberlo escrito en un REPL de Python por conveniencia, pero esa respuesta es engañosa porque esta pregunta es sobre la JVM.Dado que esta pregunta de 1 año fue lanzada por alguien que corrigió el asunto de la pregunta, y esta pregunta está etiquetada jsp, y nadie aquí pudo dar una respuesta dirigida a JSP, aquí está mi contribución dirigida a JSP.
Utilice JSTL (simplemente coloque jstl-1.2.jar en
/WEB-INF/lib
) fmt taglib. Hay una<fmt:formatNumber>
etiqueta que hace exactamente lo que quieres y de una manera bastante fácil con la ayuda demaxFractionDigits
ymaxIntegerDigits
atributos.Aquí hay un SSCCE , simplemente cópielo, péguelo y ejecútelo.
Salida:
Eso es. No es necesario masajearlo con la ayuda de código Java sin procesar.
fuente
La pregunta original pedía el exponente y la mantisa, en lugar de la parte fraccionaria y entera.
Para obtener el exponente y la mantisa de un doble, puede convertirlo en la representación IEEE 754 y extraer los bits de esta manera:
fuente
Lógica principal: primero tienes que encontrar cuántos dígitos hay después del punto decimal.
Este código funciona para cualquier número de hasta 16 dígitos. Si usa BigDecimal, puede ejecutarlo solo para hasta 18 dígitos. ponga el valor de entrada (su número) a la variable "num", aquí como ejemplo lo he codificado.
fuente
La mantisa y el exponente de un número de coma flotante doble IEEE son los valores tales que
si la mantisa tiene la forma 0.101010101_base 2 (es decir, su bit más significativo se desplaza para estar después del punto binario) y el exponente se ajusta por sesgo.
Desde 1.6, java.lang.Math también proporciona un método directo para obtener el exponente insesgado (llamado getExponent (doble))
Sin embargo, los números que solicita son las partes integrales y fraccionarias del número, que se pueden obtener usando
aunque es posible que desee tratar los números negativos de manera diferente
(floor(-3.5) == -4.0)
, dependiendo de por qué desea las dos partes.Sugiero encarecidamente que no los llame mantisa y exponente.
fuente
No sé si esto es más rápido pero estoy usando
fuente
[Editar: la pregunta originalmente preguntaba cómo obtener la mantisa y el exponente].
Donde n es el número para obtener la mantisa / exponente real:
O, para obtener la respuesta que estaba buscando:
Estos no son exactamente Java, pero deberían ser fáciles de convertir.
fuente
La parte entera se obtiene de la fundición simple y para la división de cadenas fraccionarias:
fuente
¿Qué pasa si su número es 2.39999999999999? Supongo que desea obtener el valor decimal exacto. Luego usa BigDecimal:
fuente
Dado que la
fmt:formatNumber
etiqueta no siempre produce el resultado correcto, aquí hay otro enfoque solo de JSP: simplemente formatea el número como una cadena y hace el resto del cálculo en la cadena, ya que es más fácil y no implica más puntos flotantes aritmética.fuente
fmt:formatNumber
Redondea su argumento, que no se desea en este caso.Muchas de estas respuestas tienen horribles errores de redondeo porque pasan números de un tipo a otro. Qué tal si:
fuente
Math.abs
?La respuesta aceptada no funciona bien para números negativos entre -0 y -1.0 También dé la parte fraccionaria negativa.
Por ejemplo: para el número -0,35
devoluciones
Parte entera = 0 Parte fraccionaria = -0,35
Si está trabajando con coordenadas GPS, es mejor obtener un resultado con el signo en la parte entera como:
Parte entera = -0 Parte fraccionaria = 0.35
Estos números se utilizan, por ejemplo, para las coordenadas GPS, donde es importante el signo de la posición Lat o Long
Proponer código:
Salida:
fuente
Desde Java 8, puede usar
Math.floorDiv
.Devuelve el valor más grande (más cercano al infinito positivo)
int
que es menor o igual que el cociente algebraico.Algunos ejemplos:
Alternativamente, el
/
operador se puede utilizar:Referencias:
fuente
Usaría BigDecimal para la solución. Me gusta esto:
fuente
fuente
fuente
De acuerdo, esto quizás sea tarde, pero creo que el mejor y más preciso enfoque es usar BigDecimal
fuente
input (5.03)
output int = 5 , fractional = 0.0299999
, estamos hablando de entradas y salidas, ¡pones valor y recuperas tu valor sin perder el 0.001%! ¡Y esto es exacto, no engañoso!fuente