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

104

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

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

Винаяк Бевинакатти
источник
4
Кажется, у вас неточное представление о том, что такое мантисса и показатель степени. Это не просто «целая часть» и «дробная часть». См. En.wikipedia.org/wiki/Floating_point
Джон Скит,
На самом деле я прочитал около 5 сообщений, прежде чем сказать «эй ... это не показатель степени». Мой мозг отбросил слова и начал решать проблему .. Вредные привычки чтения программирования дали мне :)
Гишу
1
Также перефразируйте вопрос OP .. для потомков среди других причин.
Гишу
1
Это подозрительно похоже на домашнее задание.
Брайан Ноблауч
Ох, я понял. Я уже задавался вопросом, откуда у него такие странные результаты
Йоханнес Шауб - лит

Ответы:

102

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
Гишу
источник
61
На самом деле эта страница - первое попадание в поисковик Google по запросу «получить дробное и целое из двойного java» =)
Крис
12
На самом деле этот ответ неверен, поскольку значения больше, чем может представлять long, будут давать огромные числа в дробной части. Ответ Дэна Винтона ниже такой же простой и всегда возвращает правильный результат.
arberg 01
2
так что на самом деле это неверно, как вы можете видеть на выходе. ввод - это дробная часть 3, а вывод - 29999999 ... использование BigDecimal вместо Double сделает свое дело,
Алекс
2
@Alex Нет, введенное число очень близко к нему 2.3, но, конечно же, нет 2.3. И в выводе нет ничего плохого, если только вам не нужно намного больше 10 действительных цифр. Все, что вам нужно, - это округление каждого вывода (например, формат %.9f), что обычно менее проблемно, чем BigDecimal. Единственная проблема здесь - переполнение.
maaartinus
1
Преобразование double в int почти всегда плохая идея. Потому что, например, for (long)1.0e100вы получите 0. Часто вам нужно, чтобы двойное значение просто "перекрывалось", для чего оно есть floor(). Если вы хотите использовать как целые, так и дробные части modf(). Действительно, это плохой ответ.
Mojuba
155
double value = 3.25;
double fractionalPart = value % 1;
double integralPart = value - fractionalPart;
Дэн Винтон
источник
12
Почему это отклонено? Работает нормально, и с моим редактированием будет работать и с отрицательными значениями.
HRJ
Целая часть может быть => long longPart = (long) 3,25
jdurango
2
Не сработает на нег. ценности. То есть -3,25% 1 = 0,75, а не 0,25. Таким образом, IntegratedPart будет -3,25 - 0,75 = -4.
WindRider
2
@WindRider, я проверил на отрицательный ... и он работает ... однако для десятичных знаков, которых мало, будет небольшая ошибка. Ex. для -03,0025 он возвращает -0,0024999999999999467 и -3,0
justshams
5
Путаница здесь заключается в том, что некоторые языки, такие как Python, используют %для обозначения modulo ( -3.25 % 1 == 0.75), а другие, такие как Java, Fortran, C и C ++, используют %для обозначения остатка ( -3.25 % 1 == -0.25). WindRider, возможно, ввел его в Python REPL для удобства, но этот ответ вводит в заблуждение, потому что этот вопрос касается JVM.
Джим Пиварски
24

Поскольку этот вопрос годичной давности был задан кем-то, кто исправил тему вопроса, и этот вопрос отмечен тегом 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>

Вывод:

Целая: 3

Фракция: 0,25

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

BalusC
источник
8

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

Чтобы получить показатель степени и мантиссу из двойника, вы можете преобразовать его в представление 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
Rasmus это не было выходом ryt Результат: экспонента 0 и мантисса 2814749767106560, и если вы выберете urs agnul, мантисса будет 0
Vinayak Bevinakatti
Сломано 4 голосами за :) Хотя я вижу, что код пытается сделать, разделяя двойное значение на его стыках, код, похоже, не выводит правильные значения.
Гишу
@agnul: Я думаю, что "мантисса" обычно относится только к значению битов. Вы можете просто преобразовать это в мантиссу, (иногда) добавив 1 бит. Но согласно Википедии, слово мантисса теперь устарело в пользу «дроби».
Расмус Фабер
5

Основная логика: вы должны сначала определить, сколько цифр стоит после десятичной точки.
Этот код работает для любого числа до 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);
OnePunchMan
источник
Чувак, это чрезвычайно сложный ответ на простую проблему. Вы посмотрели на принятый ответ?
Грей
1
Теперь человек, который проголосовал против (не я, кстати), должен был объяснить, почему было голосование против. Это не хорошо. Но все мы в тот или иной момент набирали 1 балл.
Грей
2
@Gray вопрос заключался в том, чтобы разделить 3,25 на «3» и «25», и принятый ответ никогда не даст «25», он всегда будет давать «2599999999»
OnePunchMan
@Gray Я знаю, кто проголосовал против, это был парень по имени Эджи (старый пользователь), высмеивающий каждый мой комментарий, ответ и вопросы, которые я публикую в этом блоге. Напоследок жалуюсь модератору.
OnePunchMan
2
Этот ответ очень полезен, если вы хотите, чтобы дробная часть была целым числом
Гильерме Кампос Хазан
5

Мантисса и показатель степени двойного числа с плавающей запятой 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), в зависимости от того, почему вам нужны две части.

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

Пит Киркхэм
источник
4

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

float fp = ip % 1.0f;
QED
источник
3

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

Где n - число, чтобы получить реальную мантиссу / показатель степени:

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

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

exponent = int(n)
mantissa = n - exponent

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

Стивен Дарлингтон
источник
3

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

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
Зон
источник
1

Что делать, если ваш номер 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);
ройбрайм
источник
0

Поскольку 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округляет свой аргумент, что в данном случае нежелательно.
Роланд Иллиг
0

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

double x=123.456;
double fractionalPart = x-Math.floor(x);
double wholePart = Math.floor(x);
Benofben
источник
@justshams А как насчет использования Math.abs?
Стефан
0

Принятый ответ не подходит для отрицательных чисел от -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
user1817835
источник
0

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

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

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

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

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

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

Ссылки:

Стефан
источник
0

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

    double value = 3.25;
    BigDecimal wholeValue = BigDecimal.valueOf(value).setScale(0, BigDecimal.ROUND_DOWN);
    double fractionalValue = value - wholeValue.doubleValue();
Эндери
источник
0
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
0
// 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
w__
источник
0

Хорошо, это может быть поздно, но я думаю, что лучший и более точный подход - использовать 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 не восстановит его точности волшебным образом.
Taschi
@Taschi, я думаю, речь идет о разделении целой и дробной части, а не о восстановлении ее точности!
Омар Элашри,
Омар, вы конкретно говорили о том, что ваш подход «более точен», что, на мой взгляд, не соответствует действительности. Ваш ответ вполне приемлем, но эта формулировка мне кажется вводящей в заблуждение, поэтому я прокомментировал ее.
Taschi
@Taschi, я сказал, что, поскольку во многих ответах вы теряете ценность, когда получаете результат, например input (5.03) output int = 5 , fractional = 0.0299999, мы говорим о входах и выходах, вы устанавливаете значение и получаете обратно свое значение, не теряя 0,001% от него! и это точно, а не вводит в заблуждение!
Омар Элашри,
да. Вы теряете точность, когда сохраняете что-то в первую очередь как двойное. Округление при преобразовании в BigDecimal также теряет точность. Эти две потери точности могут нейтрализовать друг друга, но это не «восстанавливает» точность, потому что восстановление точности математически невозможно. Вы не можете извлечь информацию из воздуха.
Taschi
-2
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 десятичных знака. Не иначе.
Маркиз Лорн,