Как получить целые и дробные части из double в JSP / Java?

Как получить целые и дробные части из double в JSP / Java? Если значение 3,25, то я хочу получить fractional =.25, whole = 3

Как мы можем сделать это на Java?

Кажется, у вас неточное представление о том, что такое мантисса и показатель степени. Это не просто «целая часть» и «дробная часть». См. en.wikipedia.org/wiki/Floating_point

Jon Skeet 05.12.2008 14:53

На самом деле я прочитал около 5 сообщений, прежде чем сказать «эй ... это не показатель степени». Мой мозг отбросил слова и начал решать проблему .. Вредные привычки чтения программирования дали мне :)

Gishu 05.12.2008 15:13

Также, пожалуйста, перефразируйте вопрос OP .. для потомков среди других причин.

Gishu 05.12.2008 15:17

Это подозрительно похоже на домашнее задание.

Brian Knoblauch 05.12.2008 15:34

Ох, я понял. я уже задавался вопросом, как он получает такие странные результаты

Johannes Schaub - litb 05.12.2008 15:41

Я просто не хочу знать об этой школе, если это так ... она слишком мала, чтобы тренировать какие-либо клетки мозга. :)

Gishu 05.12.2008 15:41

Сохраните исходный заголовок, иначе большинство ответов не будут иметь смысла.

Pete Kirkham 06.04.2009 16:53

Мои 5 строк кода работают для всех случаев, посмотрите здесь stackoverflow.com/a/56413634/8253662

Mahesh Jamdade 02.06.2019 12:06
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
106
8
164 593
19
Перейти к ответу Данный вопрос помечен как решенный

Ответы 19

В исходном вопросе задавался вопрос об экспоненте и мантиссе, а не о дробной и целой части.

Чтобы получить показатель степени и мантиссу из двойника, вы можете преобразовать его в представление IEEE 754 и извлечь биты следующим образом:

long bits = Double.doubleToLongBits(3.25);

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

Не является ли первый бит мантиссы неявно равным 1, поэтому мантисса должна быть (биты & 0x000fffffffffffffL) | 0x0010000000000000L?

agnul 05.12.2008 15:01

Rasmus это не было выходом ryt Output: экспонента 0 и мантисса 2814749767106560, и если u выберет urs agnul, мантисса будет 0

Vinayak Bevinakatti 05.12.2008 15:07

Сломано 4 голосами за :) Хотя я вижу, что код пытается сделать, разделяя двойное значение на его стыках, код, похоже, не выводит правильные значения.

Gishu 05.12.2008 15:26

@agnul: Я думаю, что «мантисса» обычно относится только к значению битов. Вы можете просто преобразовать это в мантиссу, (иногда) добавив 1 бит. Но согласно Википедии, слово мантисса теперь устарело и заменено словом «фракция».

Rasmus Faber 05.12.2008 16:32
double value = 3.25;
double fractionalPart = value % 1;
double integralPart = value - fractionalPart;

Почему это отклонено? Работает нормально, и с моим редактированием также будет работать с отрицательными значениями.

HRJ 30.08.2011 18:26

Целая часть может быть => long longPart = (long) 3,25

jdurango 20.02.2014 20:56

Не сработает на нег. значения. Т.е. -3,25% 1 = 0,75, а не 0,25. Таким образом, интегральная часть будет -3,25 - 0,75 = -4.

WindRider 16.04.2014 14:20

@WindRider, я проверил на отрицательный ... и он работает ... однако для десятичных знаков, которых мало, будет небольшая ошибка. Бывший. для -03.0025 он возвращает -0.0024999999999999467 и -3.0

shams.haq 17.09.2014 17:59

Путаница здесь заключается в том, что некоторые языки, такие как Python, используют % для обозначения по модулю (-3.25 % 1 == 0.75), а другие, такие как Java, Fortran, C и C++, используют % для обозначения остатка (-3.25 % 1 == -0.25). WindRider, возможно, напечатал его в Python REPL для удобства, но этот ответ вводит в заблуждение, потому что этот вопрос касается JVM.

Jim Pivarski 30.01.2015 10:12

[Обновлено: изначально задавался вопрос, как получить мантиссу и показатель степени.]

Где п - это число для получения действительной мантиссы / экспоненты:

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

Или, чтобы получить ответ, который вы искали:

exponent = int(n)
mantissa = n - exponent

Это не совсем Java, но их должно быть легко преобразовать.

Мантисса и показатель степени двойного числа с плавающей запятой IEEE являются такими значениями, что

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

если мантисса имеет вид 0.101010101_base 2 (т. е. ее самый важный бит смещен так, чтобы стоять после двоичной точки), а показатель степени корректируется с учетом смещения.

Начиная с версии 1.6, java.lang.Math также предоставляет прямой метод для получения несмещенной экспоненты (называемый getExponent (double))

Однако числа, которые вы запрашиваете, являются целой и дробной частями числа, которые можно получить с помощью

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

хотя вы можете по-разному относиться к отрицательным числам (floor(-3.5) == -4.0), в зависимости от того, зачем вам нужны две части.

Я настоятельно рекомендую вам не называть эти мантиссы и экспоненты.

Ответ принят как подходящий

http://www.java2s.com/Code/Java/Data-Type/Obptingtheintegerandfractionalparts.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);

Выходы:

Integer part = 2
Fractional part = 0.2999999999999998

На самом деле эта страница является первым попаданием в поиск Google по запросу "получить дробную и целую часть из двойного java" =)

Chris 17.05.2012 02:09

На самом деле этот ответ неверен, поскольку значения больше, чем может представлять long, он даст огромные числа в дробной части. Ответ Дэна Винтона ниже такой же простой и всегда возвращает правильный результат.

arberg 01.11.2012 16:10

так что на самом деле это неверно, как вы можете видеть на выходе. ввод - это дробная часть 3, а вывод - 29999999 ... использование BigDecimal вместо Double сделает трюк, хотя

Alex 02.07.2013 23:22

0,2999999999999 равно 0,3

Confuse 14.05.2015 19:45

@Alex Нет, введенное число очень близко к 2.3, но, конечно, не к 2.3. И в выводе нет ничего плохого, если только вам не нужно намного больше 10 действительных цифр. Все, что вам нужно, - это округление в каждом выводе (например, формат %.9f), что обычно менее болезненно, чем BigDecimal. Единственная проблема здесь - переполнение.

maaartinus 05.06.2015 00:02

Преобразование double в int почти всегда плохая идея. Потому что, например, для (long)1.0e100 вы получите 0. Часто вам нужно двойное значение, просто "наполовину", для которого есть floor(). Если вам нужны как целые, так и дробные части, используйте modf(). Действительно, это плохой ответ.

mojuba 22.01.2016 23:07
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);
    }
}

Это работает, только если число имеет ровно 4 десятичных знака. Не иначе.

user207421 01.09.2013 22:11

Поскольку этот вопрос годичной давности был задан кем-то, кто исправил тему вопроса, и этот вопрос помечен тегом jsp, и никто здесь не смог дать целевой ответ JSP, вот мой вклад, ориентированный на JSP.

Используйте JSTL (просто добавьте jstl-1.2.jar в /WEB-INF/lib) fmt taglib. Есть тег <fmt:formatNumber>, который делает именно то, что вы хотите, и довольно простым способом с помощью атрибутов maxFractionDigits и maxIntegerDigits.

Вот SSCCE, просто скопируйте и запустите его.

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

Выход:

Whole: 3

Fraction: .25

Вот и все. Нет необходимости массировать это с помощью сырого Java-кода.

Поскольку тег fmt:formatNumber не всегда дает правильный результат, вот еще один подход, основанный только на JSP: он просто форматирует число как строку и выполняет остальные вычисления в строке, так как это проще и не требует дальнейшего плавающего точечная арифметика.

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

Просто попробуйте все числа из моего примера. fmt:formatNumber округляет свой аргумент, что в данном случае нежелательно.

Roland Illig 14.03.2010 15:16

Основная логика: сначала нужно определить, сколько цифр стоит после десятичной точки. Этот код работает для любого числа до 16 цифр. Если вы используете BigDecimal, вы можете запустить его до 18 цифр. поместите входное значение (ваше число) в переменную "num", здесь в качестве примера я жестко его закодировал.

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

Чувак, это чрезвычайно сложный ответ на простую проблему. Вы посмотрели на принятый ответ?

Gray 16.10.2013 00:27

Теперь человек, который проголосовал против (не я, кстати), должен был объяснить Зачем, что голосование против было. Это не хорошо. Но все мы в тот или иной момент набирали 1 балл.

Gray 16.10.2013 00:36

@Gray вопрос заключался в том, чтобы разделить 3,25 как «3» и «25», и принятый ответ никогда не даст «25», он всегда будет давать «2599999999»

OnePunchMan 16.10.2013 00:37

@Gray Я знаю, кто проголосовал против, это был парень по имени Эджи (старый пользователь), высмеивающий все мои комментарии, ответы и вопросы, которые я публикую в этом блоге. Напоследок жалуюсь модератору.

OnePunchMan 16.10.2013 00:43

Что ж, не защищайся. Напишите простые хорошие ответы с хорошими описаниями, и у вас получится, чувак. Удачи.

Gray 16.10.2013 01:05

Этот ответ очень полезен, если вы хотите, чтобы дробная часть была целым числом.

Guilherme Campos Hazan 05.07.2016 14:48

Не знаю, быстрее ли это, но я использую

float fp = ip % 1.0f;

Многие из этих ответов содержат ужасные ошибки округления, потому что они переводят числа из одного типа в другой. Как насчет:

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

@justshams А как насчет использования Math.abs?

Stephan 27.10.2015 08:27

Принятый ответ не подходит для отрицательных чисел от -0 до -1,0. Также укажите отрицательную дробную часть.

Например: Для числа -0,35

возвращается

Целая часть = 0 Дробная часть = -0,35

Если вы работаете с координатами GPS, лучше получить результат со знаком в целой части как:

Целая часть = -0 Дробная часть = 0,35

Эти числа используются, например, для координат GPS, где важен знак для широты или долгого положения.

Предложить код:

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

Выход:

Integer part = -0
Fractional part = 0,3500

Начиная с Java 8, вы можете использовать Math.floorDiv.

Он возвращает наибольшее (ближайшее к положительной бесконечности) значение int, которое меньше или равно алгебраическому частному.

Некоторые примеры:

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

В качестве альтернативы можно использовать оператор /:

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

Использованная литература:

Я бы использовал BigDecimal для решения. Как это:

    double value = 3.25;
    BigDecimal wholeValue = BigDecimal.valueOf(value).setScale(0, BigDecimal.ROUND_DOWN);
    double fractionalValue = value - wholeValue.doubleValue();
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);
    }
}

Этот ответ был отмечен как низкое качество. Если он отвечает на вопрос, подумайте о добавлении небольшого текста, чтобы объяснить, как это работает.

lmo 04.09.2016 16:25

Что делать, если ваш номер 2.39999999999999. Я полагаю, вы хотите получить точное десятичное значение. Затем используйте 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);

Целая часть получается при простом приведении, а при дробном разбиении строк:

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

Хорошо, это может быть поздно, но я думаю, что лучший и более точный подход - использовать 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

Если у вас дубль, у него неточность с плавающей запятой. Преобразование его в BigDecimal не восстановит его точности волшебным образом.

user7655213 20.06.2020 02:47

@Taschi, я думаю, речь идет о разделении int и дробной части, а не о восстановлении их точности!

Omar Elashry 20.06.2020 17:46

Омар, вы конкретно говорили о том, что ваш подход «более точен», что, на мой взгляд, не соответствует действительности. Ваш ответ вполне приемлем, но эта формулировка мне кажется вводящей в заблуждение, поэтому я прокомментировал ее.

user7655213 20.06.2020 17:48

@Taschi, я сказал это, потому что во многих ответах вы теряете ценность, когда получаете результат, например input (5.03)output int = 5 , fractional = 0.0299999, мы говорим о входах и выходах, вы установите значение и получите обратно свое значение, не теряя 0,001% от него! и это точно, а не вводит в заблуждение!

Omar Elashry 20.06.2020 17:56

да. Вы теряете точность, когда сохраняете что-то в первую очередь как двойное. Округление при преобразовании в BigDecimal также теряет точность. Эти две потери точности могут нейтрализовать друг друга, но это не «восстанавливает» точность, потому что восстановление точности математически невозможно. Вы не можете извлечь информацию из воздуха.

user7655213 20.06.2020 18:29

Другие вопросы по теме