Você parece ter uma ideia imprecisa do que são mantissa e expoente. Eles não são apenas "parte inteira" e "parte fracionária". Consulte en.wikipedia.org/wiki/Floating_point
Jon Skeet
Na verdade, eu li cerca de 5 posts antes de dizer 'hey .. isso não é chamado de expoente'. Meu cérebro jogou as palavras para fora e começou a resolver o problema ... os maus hábitos de ler coisas de programação me deram :)
Gishu
1
Além disso, reformule a questão OP .. para a posteridade, entre outras razões.
Gishu
1
Parece um problema de dever de casa.
Brian Knoblauch
ohh eu vejo. já me perguntei como ele consegue resultados tão estranhos
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);
Saídas:
Integer part =2Fractional part =0.2999999999999998
Na verdade, esta página é o primeiro resultado em uma pesquisa do Google por "get sliceal and Whole part out from double java" =)
Chris
12
Na verdade, esta resposta está incorreta, pois valores maiores do que longos podem representar isso resultará em números enormes na parte fracionária. A resposta de Dan Vinton abaixo é igualmente simples e sempre retorna o resultado correto.
arberg 01 de
2
então, na verdade, isso não está correto, como você pode ver na saída. a entrada é uma fração de 3 e a saída é 29999999 ... usar BigDecimal em vez de Double resolverá o problema
Alex
2
@Alex Não, a entrada é um número muito próximo 2.3, mas certamente não 2.3. E não há nada de errado com a saída, a menos que você queira muito mais do que 10 dígitos válidos. Tudo o que você precisa é de alguns arredondamentos em cada saída (por exemplo, formato %.9f), que geralmente é menos trabalhoso do que BigDecimal. O único problema aqui é o estouro.
maaartinus
1
Converter double em int é quase sempre uma má ideia. Porque, por exemplo, para (long)1.0e100você obterá 0. Muitas das vezes você precisa do valor duplo simplesmente "pavimentado" para o qual existe floor(). Se você quiser usar partes integrais e fracionárias modf(). Realmente, esta é uma resposta ruim.
mojuba
155
double value =3.25;double fractionalPart = value %1;double integralPart = value - fractionalPart;
Por que isso foi rejeitado? Funciona bem, e minha edição funcionará com valores negativos também.
HRJ de
A parte inteira pode ser => longPart long = (long) 3.25
jdurango de
2
Não vai funcionar para neg. valores. Ie -3,25% 1 = 0,75 não 0,25. Portanto, integralPart será -3,25 - 0,75 = -4.
WindRider de
2
@WindRider, eu verifiquei o negativo .. e funciona .. entretanto para casas decimais que são pequenas em número, haverá um pequeno erro. Ex. para -03,0025 ele retorna -0,0024999999999999467 e -3,0
justshams
5
A confusão aqui é porque algumas linguagens, como Python, usam %para significar módulo ( -3.25 % 1 == 0.75) e outras, como Java, Fortran, C e C ++, usam %para significar resto ( -3.25 % 1 == -0.25). WindRider pode ter digitado em um REPL do Python para conveniência, mas essa resposta é enganosa porque esta pergunta é sobre a JVM.
Jim Pivarski
24
Uma vez que esta questão de 1 ano foi levantada por alguém que corrigiu o assunto da questão, e esta questão foi marcada com jsp, e ninguém aqui foi capaz de dar uma resposta direcionada ao JSP, aqui está minha contribuição direcionada ao JSP.
Use JSTL (apenas uma gota jstl-1.2.jar em /WEB-INF/lib) fmt taglib. Existe uma <fmt:formatNumber>tag que faz exatamente o que você deseja e de uma forma bastante fácil com ajuda de maxFractionDigitse maxIntegerDigitsatributos.
<%@ 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>
Resultado:
Inteiro: 3
Fração: 0,25
É isso aí. Não há necessidade de massagear com a ajuda de código Java bruto.
O primeiro bit da mantinssa não é implicitamente definido como 1, então a mantissa deve ser (bits & 0x000fffffffffffffL) | 0x0010000000000000L?
agnul
Rasmus não era uma saída ryt Saída: expoente 0 e mantissa 2814749767106560 e se vc escolher urs agnul a mantissa é 0
Vinayak Bevinakatti
Quebrado com 4 votos positivos :) Embora eu veja o que o código está tentando fazer com a desmontagem do valor duplo em suas juntas, o código não parece gerar os valores corretos.
Gishu
@agnul: Acho que "mantissa" geralmente se refere apenas ao valor dos bits. Você pode apenas converter isso para o significando (às vezes) acrescentando 1 bit. Mas de acordo com a Wikipedia, a palavra mantissa agora é preterida em favor de "fração".
Rasmus Faber
5
Lógica principal, você deve primeiro descobrir quantos dígitos existem após o ponto decimal.
Este código funciona para qualquer número de até 16 dígitos. Se você usar BigDecimal, poderá executá-lo com até 18 dígitos. coloque o valor de entrada (seu número) na variável "num", aqui como um exemplo, codifiquei-o.
Cara, essa é uma resposta extremamente complicada para um problema simples. Você deu uma olhada na resposta aceita?
Gray,
1
Agora, a pessoa que fez o voto negativo (não eu, aliás) deveria ter explicado por que houve um voto negativo. Isso não é bom. Mas todos nós tínhamos uma pontuação de 1 em algum ponto ou outro.
Gray,
2
@Gray, a questão era separar 3.25 como '3' e '25', e a resposta aceita nunca fornecerá '25', sempre fornecerá '2599999999'
OnePunchMan
@Gray Eu sei quem deu downvote, foi um cara chamado Eji (usuário antigo) zombando de cada um dos meus comentários, respostas e perguntas que eu posto neste blog. Finalmente, reclamo com o moderador.
OnePunchMan de
2
Esta resposta é muito útil se você quiser a parte fracionária como um inteiro
Guilherme Campos Hazan
5
A mantissa e o expoente de um número de ponto flutuante duplo IEEE são os valores tais que
value = sign *(1+ mantissa)* pow(2, exponent)
se a mantissa é da forma 0,101010101_base 2 (ou seja, seu bit mais significativo é deslocado para estar após o ponto binário) e o expoente é ajustado para polarização.
Desde 1.6, java.lang.Math também fornece um método direto para obter o expoente imparcial (chamado getExponent (double))
No entanto, os números que você está pedindo são as partes integrais e fracionárias do número, que podem ser obtidas usando
integral =Math.floor(x)
fractional = x -Math.floor(x)
embora você possa tratar os números negativos de forma diferente (floor(-3.5) == -4.0), dependendo do motivo pelo qual deseja as duas partes.
Eu sugiro fortemente que você não os chame de mantissa e expoente.
A parte inteira obtém da conversão simples e para a divisão de string fracionária:
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
Visto que a fmt:formatNumbertag nem sempre produz o resultado correto, aqui está outra abordagem apenas JSP: ela apenas formata o número como string e faz o resto do cálculo na string, já que é mais fácil e não envolve mais ponto flutuante aritmética.
A resposta aceita não funciona bem para números negativos entre -0 e -1,0. Forneça também a parte fracionária negativa.
Por exemplo: Para o número -0,35
retorna
Parte inteira = 0 Parte fracionária = -0,35
Se você estiver trabalhando com coordenadas GPS, é melhor ter um resultado com o sinal na parte inteira como:
Parte inteira = -0 Parte fracionária = 0,35
Esses números são usados, por exemplo, para coordenadas de GPS, onde são importantes o sinal para a posição Lat ou Longa
Propor 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));
double value =3.25;BigDecimal wholeValue =BigDecimal.valueOf(value).setScale(0,BigDecimal.ROUND_DOWN);double fractionalValue = value - wholeValue.doubleValue();
Esta resposta foi marcada como de baixa qualidade. Se responder à pergunta, considere adicionar um pouco de texto para explicar como 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
Se você tiver um duplo, ele terá imprecisão de float. Convertê-lo em um BigDecimal não restaurará magicamente sua precisão.
Taschi
@Taschi acho que a questão é separar o int e a parte fracionária, e não restaurar sua precisão!
Omar Elashry
Omar, você falou especificamente sobre sua abordagem ser "mais precisa", o que eu acho que simplesmente não é verdade. Sua resposta é totalmente aceitável, mas essa formulação me parece enganosa, e é por isso que comentei sobre ela.
Taschi de
@Taschi, eu disse isso porque em muitas respostas você perde valor quando obtém a saída, por exemplo input (5.03)output int = 5 , fractional = 0.0299999, estamos falando de entradas e saídas, você coloca valor e recupera seu valor sem perder 0,001% dele! e isso é preciso, não enganoso!
Omar Elashry
sim. Você perde a precisão quando armazena algo como um duplo em primeiro lugar. O arredondamento ao converter para um BigDecimal também perde a precisão. Essas duas perdas de precisão podem se anular, mas isso não "restaura" a precisão, porque restaurar a precisão é matematicamente impossível. Você não pode extrair informações do nada.
Respostas:
http://www.java2s.com/Code/Java/Data-Type/Obtainingtheintegerandfractionalparts.htm
Saídas:
fonte
2.3
, mas certamente não2.3
. E não há nada de errado com a saída, a menos que você queira muito mais do que 10 dígitos válidos. Tudo o que você precisa é de alguns arredondamentos em cada saída (por exemplo, formato%.9f
), que geralmente é menos trabalhoso do queBigDecimal
. O único problema aqui é o estouro.(long)1.0e100
você obterá 0. Muitas das vezes você precisa do valor duplo simplesmente "pavimentado" para o qual existefloor()
. Se você quiser usar partes integrais e fracionáriasmodf()
. Realmente, esta é uma resposta ruim.fonte
%
para significar módulo (-3.25 % 1 == 0.75
) e outras, como Java, Fortran, C e C ++, usam%
para significar resto (-3.25 % 1 == -0.25
). WindRider pode ter digitado em um REPL do Python para conveniência, mas essa resposta é enganosa porque esta pergunta é sobre a JVM.Uma vez que esta questão de 1 ano foi levantada por alguém que corrigiu o assunto da questão, e esta questão foi marcada com jsp, e ninguém aqui foi capaz de dar uma resposta direcionada ao JSP, aqui está minha contribuição direcionada ao JSP.
Use JSTL (apenas uma gota jstl-1.2.jar em
/WEB-INF/lib
) fmt taglib. Existe uma<fmt:formatNumber>
tag que faz exatamente o que você deseja e de uma forma bastante fácil com ajuda demaxFractionDigits
emaxIntegerDigits
atributos.Aqui está um SSCCE , apenas copie e cole e execute -o.
Resultado:
É isso aí. Não há necessidade de massagear com a ajuda de código Java bruto.
fonte
A pergunta original pedia o expoente e a mantissa, ao invés da parte fracionária e inteira.
Para obter o expoente e a mantissa de um duplo, você pode convertê-lo na representação IEEE 754 e extrair os bits assim:
fonte
Lógica principal, você deve primeiro descobrir quantos dígitos existem após o ponto decimal.
Este código funciona para qualquer número de até 16 dígitos. Se você usar BigDecimal, poderá executá-lo com até 18 dígitos. coloque o valor de entrada (seu número) na variável "num", aqui como um exemplo, codifiquei-o.
fonte
A mantissa e o expoente de um número de ponto flutuante duplo IEEE são os valores tais que
se a mantissa é da forma 0,101010101_base 2 (ou seja, seu bit mais significativo é deslocado para estar após o ponto binário) e o expoente é ajustado para polarização.
Desde 1.6, java.lang.Math também fornece um método direto para obter o expoente imparcial (chamado getExponent (double))
No entanto, os números que você está pedindo são as partes integrais e fracionárias do número, que podem ser obtidas usando
embora você possa tratar os números negativos de forma diferente
(floor(-3.5) == -4.0)
, dependendo do motivo pelo qual deseja as duas partes.Eu sugiro fortemente que você não os chame de mantissa e expoente.
fonte
Não sei se isso é mais rápido, mas estou usando
fonte
[Editar: a questão originalmente perguntada como obter a mantissa e o expoente.]
Onde n é o número para obter a mantissa / expoente real:
Ou, para obter a resposta que você estava procurando:
Eles não são exatamente Java, mas devem ser fáceis de converter.
fonte
A parte inteira obtém da conversão simples e para a divisão de string fracionária:
fonte
E se o seu número for 2.39999999999999. Suponho que você deseja obter o valor decimal exato. Em seguida, use BigDecimal:
fonte
Visto que a
fmt:formatNumber
tag nem sempre produz o resultado correto, aqui está outra abordagem apenas JSP: ela apenas formata o número como string e faz o resto do cálculo na string, já que é mais fácil e não envolve mais ponto flutuante aritmética.fonte
fmt:formatNumber
arredonda seu argumento, o que não é desejado neste caso.Muitas dessas respostas têm erros de arredondamento horríveis porque estão lançando números de um tipo para outro. E se:
fonte
Math.abs
?A resposta aceita não funciona bem para números negativos entre -0 e -1,0. Forneça também a parte fracionária negativa.
Por exemplo: Para o número -0,35
retorna
Parte inteira = 0 Parte fracionária = -0,35
Se você estiver trabalhando com coordenadas GPS, é melhor ter um resultado com o sinal na parte inteira como:
Parte inteira = -0 Parte fracionária = 0,35
Esses números são usados, por exemplo, para coordenadas de GPS, onde são importantes o sinal para a posição Lat ou Longa
Propor código:
Resultado:
fonte
Desde Java 8, você pode usar
Math.floorDiv
.Ele retorna o maior valor (mais próximo do infinito positivo)
int
que é menor ou igual ao quociente algébrico.Alguns exemplos:
Alternativamente, o
/
operador pode ser usado:Referências:
fonte
Eu usaria BigDecimal para a solução. Como isso:
fonte
fonte
fonte
OK, talvez seja tarde, mas acho que a abordagem melhor e mais precisa é usar BigDecimal
fonte
input (5.03)
output int = 5 , fractional = 0.0299999
, estamos falando de entradas e saídas, você coloca valor e recupera seu valor sem perder 0,001% dele! e isso é preciso, não enganoso!fonte