Кажется, у вас неточное представление о том, что такое мантисса и показатель степени. Это не просто «целая часть» и «дробная часть». См. En.wikipedia.org/wiki/Floating_point
Джон Скит,
На самом деле я прочитал около 5 сообщений, прежде чем сказать «эй ... это не показатель степени». Мой мозг отбросил слова и начал решать проблему .. Вредные привычки чтения программирования дали мне :)
Гишу
1
Также перефразируйте вопрос OP .. для потомков среди других причин.
Гишу
1
Это подозрительно похоже на домашнее задание.
Брайан Ноблауч
Ох, я понял. Я уже задавался вопросом, откуда у него такие странные результаты
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 =2Fractional part =0.2999999999999998
На самом деле эта страница - первое попадание в поисковик 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;
Почему это отклонено? Работает нормально, и с моим редактированием будет работать и с отрицательными значениями.
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атрибутами.
<%@ 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-кода.
Разве первый бит мантиссы неявно установлен в 1, поэтому мантисса должна быть (биты & 0x000fffffffffffffL) | 0x0010000000000000L?
agnul 05
Rasmus это не было выходом ryt Результат: экспонента 0 и мантисса 2814749767106560, и если вы выберете urs agnul, мантисса будет 0
Vinayak Bevinakatti
Сломано 4 голосами за :) Хотя я вижу, что код пытается сделать, разделяя двойное значение на его стыках, код, похоже, не выводит правильные значения.
Гишу
@agnul: Я думаю, что "мантисса" обычно относится только к значению битов. Вы можете просто преобразовать это в мантиссу, (иногда) добавив 1 бит. Но согласно Википедии, слово мантисса теперь устарело в пользу «дроби».
Расмус Фабер
5
Основная логика: вы должны сначала определить, сколько цифр стоит после десятичной точки.
Этот код работает для любого числа до 16 цифр. Если вы используете BigDecimal, вы можете запускать его до 18 цифр. поместите входное значение (ваше число) в переменную "num", здесь в качестве примера я жестко его закодировал.
Чувак, это чрезвычайно сложный ответ на простую проблему. Вы посмотрели на принятый ответ?
Грей
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), в зависимости от того, почему вам нужны две части.
Я настоятельно рекомендую вам не называть эти мантиссы и экспоненты.
Целая часть получается от простого приведения, а при дробном - разбиения строк:
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
Поскольку fmt:formatNumberтег не всегда дает правильный результат, вот еще один подход, основанный только на JSP: он просто форматирует число как строку и выполняет остальные вычисления в строке, поскольку это проще и не требует дополнительных операций с плавающей запятой. арифметика.
Принятый ответ не подходит для отрицательных чисел от -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));
double value =3.25;BigDecimal wholeValue =BigDecimal.valueOf(value).setScale(0,BigDecimal.ROUND_DOWN);double fractionalValue = value - wholeValue.doubleValue();
Этот ответ был отмечен как низкое качество. Если он отвечает на вопрос, подумайте о добавлении небольшого текста, чтобы объяснить, как это работает.
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
Если у вас дубль, у него неточность с плавающей запятой. Преобразование его в BigDecimal не восстановит его точности волшебным образом.
Taschi
@Taschi, я думаю, речь идет о разделении целой и дробной части, а не о восстановлении ее точности!
Омар Элашри,
Омар, вы конкретно говорили о том, что ваш подход «более точен», что, на мой взгляд, не соответствует действительности. Ваш ответ вполне приемлем, но эта формулировка мне кажется вводящей в заблуждение, поэтому я прокомментировал ее.
Taschi
@Taschi, я сказал, что, поскольку во многих ответах вы теряете ценность, когда получаете результат, например input (5.03)output int = 5 , fractional = 0.0299999, мы говорим о входах и выходах, вы устанавливаете значение и получаете обратно свое значение, не теряя 0,001% от него! и это точно, а не вводит в заблуждение!
Омар Элашри,
да. Вы теряете точность, когда сохраняете что-то в первую очередь как двойное. Округление при преобразовании в BigDecimal также теряет точность. Эти две потери точности могут нейтрализовать друг друга, но это не «восстанавливает» точность, потому что восстановление точности математически невозможно. Вы не можете извлечь информацию из воздуха.
Ответы:
http://www.java2s.com/Code/Java/Data-Type/Obptingtheintegerandfractionalparts.htm
Выходы:
источник
2.3
, но, конечно же, нет2.3
. И в выводе нет ничего плохого, если только вам не нужно намного больше 10 действительных цифр. Все, что вам нужно, - это округление каждого вывода (например, формат%.9f
), что обычно менее проблемно, чемBigDecimal
. Единственная проблема здесь - переполнение.(long)1.0e100
вы получите 0. Часто вам нужно, чтобы двойное значение просто "перекрывалось", для чего оно естьfloor()
. Если вы хотите использовать как целые, так и дробные частиmodf()
. Действительно, это плохой ответ.источник
%
для обозначения modulo (-3.25 % 1 == 0.75
), а другие, такие как Java, Fortran, C и C ++, используют%
для обозначения остатка (-3.25 % 1 == -0.25
). WindRider, возможно, ввел его в Python REPL для удобства, но этот ответ вводит в заблуждение, потому что этот вопрос касается JVM.Поскольку этот вопрос годичной давности был задан кем-то, кто исправил тему вопроса, и этот вопрос отмечен тегом jsp, и никто здесь не смог дать целевой ответ JSP, вот мой вклад, ориентированный на JSP.
Использование JSTL (только падение JSTL-1.2.jar в
/WEB-INF/lib
) FMT TagLib. Там есть<fmt:formatNumber>
тег , который делает именно то , что вы хотите , и в довольно легкой форме с помощьюmaxFractionDigits
иmaxIntegerDigits
атрибутами.Вот SSCCE , просто скопируйте и запустите его.
Вывод:
Вот и все. Нет необходимости массировать это с помощью сырого Java-кода.
источник
В исходном вопросе задавался вопрос об экспоненте и мантиссе, а не о дробной и целой части.
Чтобы получить показатель степени и мантиссу из двойника, вы можете преобразовать его в представление IEEE 754 и извлечь биты следующим образом:
источник
Основная логика: вы должны сначала определить, сколько цифр стоит после десятичной точки.
Этот код работает для любого числа до 16 цифр. Если вы используете BigDecimal, вы можете запускать его до 18 цифр. поместите входное значение (ваше число) в переменную "num", здесь в качестве примера я жестко его закодировал.
источник
Мантисса и показатель степени двойного числа с плавающей запятой IEEE являются такими значениями, что
если мантисса имеет вид 0.101010101_base 2 (т. е. ее самый важный бит смещен так, чтобы стоять после двоичной точки), а показатель степени корректируется для смещения.
Начиная с версии 1.6, java.lang.Math также предоставляет прямой метод для получения несмещенной экспоненты (называемый getExponent (double))
Однако запрашиваемые числа - это целая и дробная части числа, которые можно получить с помощью
хотя вы можете рассматривать отрицательные числа по-разному
(floor(-3.5) == -4.0)
, в зависимости от того, почему вам нужны две части.Я настоятельно рекомендую вам не называть эти мантиссы и экспоненты.
источник
Не знаю, быстрее ли это, но я использую
источник
[Изменить: изначально задавался вопрос, как получить мантиссу и показатель степени.]
Где n - число, чтобы получить реальную мантиссу / показатель степени:
Или, чтобы получить ответ, который вы искали:
Это не совсем Java, но их легко преобразовать.
источник
Целая часть получается от простого приведения, а при дробном - разбиения строк:
источник
Что делать, если ваш номер 2.39999999999999. Я полагаю, вы хотите получить точное десятичное значение. Затем используйте BigDecimal:
источник
Поскольку
fmt:formatNumber
тег не всегда дает правильный результат, вот еще один подход, основанный только на JSP: он просто форматирует число как строку и выполняет остальные вычисления в строке, поскольку это проще и не требует дополнительных операций с плавающей запятой. арифметика.источник
fmt:formatNumber
округляет свой аргумент, что в данном случае нежелательно.Многие из этих ответов содержат ужасные ошибки округления, потому что они переводят числа из одного типа в другой. Как насчет:
источник
Math.abs
?Принятый ответ не подходит для отрицательных чисел от -0 до -1,0. Также укажите отрицательную дробную часть.
Например: для числа -0,35
возвращается
Целая часть = 0 Дробная часть = -0,35
Если вы работаете с координатами GPS, лучше получить результат со знаком в целой части как:
Целая часть = -0 Дробная часть = 0,35
Эти числа используются, например, для координат GPS, где важен знак для широты или долгого положения.
Предложить код:
Вывод:
источник
Начиная с Java 8, вы можете использовать
Math.floorDiv
.Он возвращает наибольшее (ближайшее к положительной бесконечности)
int
значение, которое меньше или равно алгебраическому частному.Некоторые примеры:
В качестве альтернативы
/
можно использовать оператор:Ссылки:
источник
Я бы использовал BigDecimal для решения. Как это:
источник
источник
источник
Хорошо, это может быть поздно, но я думаю, что лучший и более точный подход - использовать BigDecimal
источник
input (5.03)
output int = 5 , fractional = 0.0299999
, мы говорим о входах и выходах, вы устанавливаете значение и получаете обратно свое значение, не теряя 0,001% от него! и это точно, а не вводит в заблуждение!источник