С Новым годом! Форум программистов, компьютерный форум, киберфорум
Java SE (J2SE)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.54/35: Рейтинг темы: голосов - 35, средняя оценка - 4.54
44 / 44 / 11
Регистрация: 21.01.2013
Сообщений: 668

Почему для Double и для Integer переполнение работает по разному?

31.05.2014, 16:09. Показов 7074. Ответов 18
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
забавный код

Java
1
2
System.out.println(Double.MAX_VALUE+23414 == Double.MAX_VALUE);//true
System.out.println(Integer.MAX_VALUE+23414 == Integer.MAX_VALUE);//false

вывод

true
false
как объясните?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
31.05.2014, 16:09
Ответы с готовыми решениями:

Ошибка с циклом While. По разному работает с double и float, хотя должен бы одинаково
Здравствуйте. Абсолютно не понимаю, почему double x; //--- x=0.1; while(x <= 0.3) { //--- x+=0.2;

Почему операторы инкремента действуют по разному для стандартных и нестандартных типов?
class my { int i; public: my(int in) :i(in) {} operator int () { return i; } int operator=(int...

Почему работает по-разному?
Почему работает по-разному? cout << "Hello, world! \n"; printf("%s\n","By, world!"); By, world! Hello, world! cout...

18
61 / 61 / 19
Регистрация: 06.09.2013
Сообщений: 236
Записей в блоге: 1
31.05.2014, 16:38
Это действительно интересно. Работая с Double примитивом, мы не можем выйти "за рамки".
Насколько мы помним, JVM выделяет под double 64 бита памяти, ровно столько же, как и под long.

Теперь попробуем небольшую магию.
Java
1
2
3
4
        long a = (long) Double.MAX_VALUE;
        long b = new Double(4456).longValue();
        System.out.println(a - b); // 9223372036854771351
        System.out.println(a);      // 9223372036854775807
В итоге, значения в типе long меняются без проблем.

Полагаю, это какой-то трюк компилятора, по-видимому, разработчиками было задумано, что за рамки Максимального/минимального значения в примитиве Double выходить нельзя...
0
44 / 44 / 11
Регистрация: 21.01.2013
Сообщений: 668
31.05.2014, 18:23  [ТС]
Freedomen,
Java
1
2
System.out.println(Double.MAX_VALUE+Double.MAX_VALUE/100000000000000000. == Double.MAX_VALUE);// --> true
System.out.println(Double.MAX_VALUE+Double.MAX_VALUE/10000000000000000. == Double.MAX_VALUE); //-->false
Добавлено через 1 минуту
Работая с Double примитивом, мы не можем выйти "за рамки".
можете это как-то аргументировать?

Добавлено через 4 минуты
Мне кажется это связано с тем, что числа с плавающей точкой это мантисса+порядок

ближе к нулю порядок маленький, следовательно плотность точек большая, а ближе к Double.MAX_VALUE порядок большой и расстояние между соседними точками разряженное.

хотелось бы узнать про Double.MAX_VALUE и INFINITY

и как это соотносится с Float и с примитивами

Добавлено через 1 минуту
Цитата Сообщение от Freedomen Посмотреть сообщение
JVM выделяет под double 64 бита памяти, ровно столько же, как и под long
имхо это ничего не значит. механизм хранения другой. они хранят разную информацию
0
2838 / 1647 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
31.05.2014, 18:33
http://docs.oracle.com/javase/... #jls-4.2.3
http://ru.wikipedia.org/wiki/IEEE_754-2008
http://en.wikipedia.org/wiki/IEEE_floating_point
0
44 / 44 / 11
Регистрация: 21.01.2013
Сообщений: 668
31.05.2014, 18:50  [ТС]
Somebody,

там вообще многовато буков для нашей конкретной беседы)

что мне показалось относящимся к делу:
The integer operators do not indicate overflow or underflow in any way.
A floating-point operation that overflows produces a signed infinity.
Похоже, что разрез примитив/не примитив не подходит, а подходит разрез целочисленные/с плавающей запятой
0
61 / 61 / 19
Регистрация: 06.09.2013
Сообщений: 236
Записей в блоге: 1
31.05.2014, 19:26
Это надо изучить современные компиляторы java, чтобы точно сказать - почему именно так. Вообще, Double тип изначально был разработан для хранения очень больших значений. К примеру, если вы работаете в области физики и считаете количество молекул во Вселенной, вряд ли это значение полностью поместится в int или даже long. Хотя есть BigInteger, но это несколько другая область.

Мне кажется, секрет таится в восприятии бесконечности разработчиками Java платформы. Возможно, пытаясь добавить что-то еще к максимуму, можно получить бесконечность, что уже перейдет в другую область математического восприятия чисел и реальности в целом. Именно поэтому они ограничивают возможные операции с double типом.

Добавлено через 12 минут
Интересненько.

Java
1
2
System.out.println((Double.MAX_VALUE + 0.1e-300) == Double.MAX_VALUE); // true
System.out.println((Double.MAX_VALUE * 0.1e-300) == Double.MAX_VALUE); // false
Но здесь, кажется все понятно. При умножении обычно результат получается намного больше/меньше исходного, а при сложении - нет. Тогда, возможно, если к очень большому прибавлять что-то маленькое, то по логике архитекторов Java это вряд ли выйдет за границы, а если умножить на что-то -может получиться результат, превышающий во много раз максимум.

Добавлено через 1 минуту
Вот пример в док-во предыдущему посту.

Java
1
System.out.println((Double.MAX_VALUE + (0.1 * 500e+300)) == Double.MAX_VALUE); // false
Кажется, мы близки к истине.

Добавлено через 2 минуты
Действительно, это так, как я предполагал. В примере мы прибавляем очень большое число к максимуму, тем самым переходя в стадию бесконечности.

Java
1
System.out.println(Double.isInfinite((Double.MAX_VALUE + (0.1 * 500e+300)))); // true
Добавлено через 5 минут
Все оказалось действительно так. Пример:

Java
1
System.out.println(Double.isInfinite((Double.MAX_VALUE + (1000)))); // false
То есть, по мнению архитекторов Java, есть определенный лимит, при добавлении которого к максимальному значению double - число не перейдет в стадию бесконечности, а значит и это число близко к максимальному значению.
1
44 / 44 / 11
Регистрация: 21.01.2013
Сообщений: 668
01.06.2014, 00:49  [ТС]
Freedomen, я бы добавил ещё к вашим словам свои)
Мне кажется это связано с тем, что числа с плавающей точкой это мантисса+порядок

ближе к нулю порядок маленький, следовательно плотность точек большая, а ближе к Double.MAX_VALUE порядок большой и расстояние между соседними точками разряженное.
это объясняет почему именно так сделано.

Добавлено через 1 минуту
Freedomen,
таким образом можно вычислить расстояние между Double.MaxValue и Infinity. Может так и получится, что с учётом погрешности между ними один только шаг.
1
 Аватар для KuKu
1563 / 1041 / 94
Регистрация: 17.04.2009
Сообщений: 2,995
01.06.2014, 11:18
Поиграйте степенями у small
Java
1
2
3
4
5
6
7
8
9
10
    public static void main(String[] arg) {
        double big = 1d;
        double small = 1e-16;
 
        if (big == big + small) {
            System.out.println("100%");
        } else {
            System.out.println("never");
        }
    }
Все дело в количестве значащих цифр у дабла и арифметики оного. Для Double.MAX_VALUE, значение 23414 можно сказать равно нулю. У лонга этого нет, потому что это точный тип.
0
44 / 44 / 11
Регистрация: 21.01.2013
Сообщений: 668
01.06.2014, 15:19  [ТС]
Java
1
2
System.out.println(Math.nextUp(1.0));//1.0000000000000002
System.out.println(Math.nextUp(Double.MAX_VALUE));//Infinity
0
61 / 61 / 19
Регистрация: 06.09.2013
Сообщений: 236
Записей в блоге: 1
01.06.2014, 18:39
Да собственно мы с gredwhite уже нашли ответ. Но забавно, что разработчики в API ни слова об этой грани не упомянули...
0
 Аватар для KuKu
1563 / 1041 / 94
Регистрация: 17.04.2009
Сообщений: 2,995
01.06.2014, 20:58
Это не совсем грань. У double примерно 16 значащих цифр - все остальные цифры, которые получаются при сложении отбрасываются. Когда Double.MAX_VALUE складывается с 23414, то чтобы записать полученное число надо 308 значащих цифр. Первые 16 цифр остаются, а все остальные отбрасываются - и эти отброшенные как раз и приходятся на число 23414.

Первая строка попадет в значащ. цифры и будет бесконечность, вторая - не попадет.
Java
1
2
System.out.println(Double.MAX_VALUE+Double.MAX_VALUE*1e-16);
System.out.println(Double.MAX_VALUE+Double.MAX_VALUE*1e-17);
Это обычная арифметика, и вроде как для всех языков одинаковая.
Math.nextUp на сколько понял, просто прибавляет к младшему биту единичку, т.е сразу меняет последнюю знач. цифру.
0
44 / 44 / 11
Регистрация: 21.01.2013
Сообщений: 668
01.06.2014, 21:51  [ТС]
Цитата Сообщение от KuKu Посмотреть сообщение
У double примерно 16 значащих цифр
всего? всмысле до и после запятой?
0
 Аватар для KuKu
1563 / 1041 / 94
Регистрация: 17.04.2009
Сообщений: 2,995
01.06.2014, 22:24
На мантиссу - всего.
0
44 / 44 / 11
Регистрация: 21.01.2013
Сообщений: 668
01.06.2014, 23:00  [ТС]
Цитата Сообщение от KuKu Посмотреть сообщение
Это обычная арифметика, и вроде как для всех языков одинаковая.
Да, да - это очень важно на мой взгляд.

Цитата Сообщение от KuKu Посмотреть сообщение
На мантиссу - всего.
так на мантиссу или на результат умножения мантиссы на порядок?

Добавлено через 26 минут
KuKu,
ну допустим в мантиссе 40 знаков, а порядок равен 10

Если у нас 16 значащих знаков, то у нас число будет иметь точность до 6 цифры после запятой?

То есть из 40 знаков мантиссы мы можем забыть про последние 24?
0
 Аватар для KuKu
1563 / 1041 / 94
Регистрация: 17.04.2009
Сообщений: 2,995
01.06.2014, 23:17
Цитата Сообщение от gredwhite Посмотреть сообщение
так на мантиссу или на результат умножения мантиссы на порядок?
Не совсем понял вопрос, количество значащих цифр определяется мантиссой. До или после запятой не сильно влияет на это. Посмотрите IEEE 754 - как хранится, и примерные эффекты на пальцах.
0
44 / 44 / 11
Регистрация: 21.01.2013
Сообщений: 668
02.06.2014, 00:00  [ТС]
Цитата Сообщение от KuKu Посмотреть сообщение
До или после запятой не сильно влияет на это

имхо вообще никак не влияет)

Цитата Сообщение от gredwhite Посмотреть сообщение
допустим в мантиссе 40 знаков, а порядок равен 10
Если у нас 16 значащих знаков, то у нас число будет иметь точность до 6 цифры после запятой?
То есть из 40 знаков мантиссы мы можем забыть про последние 24?

с этим вы согласны?
0
 Аватар для KuKu
1563 / 1041 / 94
Регистрация: 17.04.2009
Сообщений: 2,995
02.06.2014, 09:00
Цитата Сообщение от gredwhite Посмотреть сообщение
имхо вообще никак не влияет)
При переводе из нашей 10ой системы счисления и всяких нормализациях по-моему есть какие-то эффекты - ща сходу не скажу, не сильно вникал в детали.

Цитата Сообщение от gredwhite Посмотреть сообщение
KuKu,
ну допустим в мантиссе 40 знаков, а порядок равен 10
Если у нас 16 значащих знаков, то у нас число будет иметь точность до 6 цифры после запятой?
То есть из 40 знаков мантиссы мы можем забыть про последние 24?
Не совсем понимаю вопрос, тут термины как-то хитро переплетаются)
Если у нас есть десятичное число из 40 десятичных знаков. А мы можем хранить только 16 десятичных знаков, то последние 24 от нас уйдут.
0
44 / 44 / 11
Регистрация: 21.01.2013
Сообщений: 668
02.06.2014, 09:25  [ТС]
Цитата Сообщение от KuKu Посмотреть сообщение
При переводе из нашей 10ой системы счисления и всяких нормализациях по-моему есть какие-то эффекты - ща сходу не скажу, не сильно вникал в детали.
не все десятичные числа представимы в двоичной системе счисления....Есть какое-то наколеночное правило - что-то там со степенью двойки у знаменателя дроби....

Цитата Сообщение от KuKu Посмотреть сообщение
Не совсем понимаю вопрос, тут термины как-то хитро переплетаются)
Если у нас есть десятичное число из 40 десятичных знаков. А мы можем хранить только 16 десятичных знаков, то последние 24 от нас уйдут.
тоже хотел бы уйти от терминов к конкретике)
допустим работаем с double

d3 = d1+d2;

d1 - большое число
d2 - поменьше.

Правильно я понимаю, что если первые 16(17) цифр суммы и d1 будут совпадать, то d3 == d1 -> true?
0
 Аватар для KuKu
1563 / 1041 / 94
Регистрация: 17.04.2009
Сообщений: 2,995
02.06.2014, 09:35
Цитата Сообщение от gredwhite Посмотреть сообщение
d3 = d1+d2;
d1 - большое число
d2 - поменьше.
Правильно я понимаю, что если первые 16(17) цифр суммы и d1 будут совпадать, то d3 == d1 -> true?
Ну для этого пример и приводился
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
02.06.2014, 09:35
Помогаю со студенческими работами здесь

почему в разных ОС по разному работает IntelliJ
Привет всем! собственно сабж, далее вкладываю два скриншота: 1) ОС Линукс Дебиан 8 2) ОС Винда 10 обоих случаях IDE была скачана...

Почему функция strchr по разному работает при разных строках?
Только начал изучать С. Пользую Borland C++ v.3.1 Нужно работать со строками. Вот стандартный пример из стандартного хелпа компилятора: ...

Почему в WEB приложении и в обычном один и тот же код по разному работает?
static Boolean Auth(String data) { String dbURL = "jdbc:mysql://192.168.0.150:3306/SBP_db"; String username...

Почему не работает цикл while для заполнения и do while для вывода массива?
//--------------------------------------------------------------------------- #include <vcl.h> #include <conio.h> #include...

Не корректно работает допустимый диапазон для double [Range(typeof(double), "0,00", "49,99")]
Здравствуйте. Имеется простой класс: public class AutoPart { public int AutoPartId { get; set; }


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути
Programma_Boinc 01.01.2026
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути Сочетание глобально распределённой вычислительной мощности и инновационных. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru