powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / предсказуем ли результат?
25 сообщений из 54, страница 1 из 3
предсказуем ли результат?
    #38537888
redwhite90
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
возможно без компилятора предсказать результат выполнения такого выражения?
Код: java
1.
 System.out.println(0.3==0.1+0.1+0.1);
...
Рейтинг: 0 / 0
предсказуем ли результат?
    #38537892
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да
...
Рейтинг: 0 / 0
предсказуем ли результат?
    #38537894
redwhite90
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
забыл ник,

научишь?
...
Рейтинг: 0 / 0
предсказуем ли результат?
    #38537899
redwhite90
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
вроде как если дробная часть без потерь переводится в 2 СС, то будет тру, а в остальных случаях по разному.
...
Рейтинг: 0 / 0
предсказуем ли результат?
    #38537905
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
redwhite90,

У меня такой результат:
Код: java
1.
2.
System.out.println(0.3F == 0.1F + 0.1F + 0.1F); // true
System.out.println(0.3 == 0.1 + 0.1 + 0.1); // false

redwhite90возможно без компилятора предсказать результат выполнения такого выражения?С типом double не получится. (имхо)
...
Рейтинг: 0 / 0
предсказуем ли результат?
    #38537908
redwhite90
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Usman,

вроде как по последней значащей цифре мантиссы это определяется( хотя не уверен)

во всяком случае эта версия объясняет разные результаты для float и double.

P.S.

Код: java
1.
2.
 System.out.println(0.5==0.1+0.1+0.1+0.1+0.1);//true
        System.out.println(0.5f==0.1f+0.1f+0.1f+0.1f+0.1f); //true




0.5 переводится в 2 СС без потерь.
...
Рейтинг: 0 / 0
предсказуем ли результат?
    #38537909
rdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
предсказуем ли результат?
    #38537914
redwhite90
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdm,

да, проблема та, но это не ответ.
...
Рейтинг: 0 / 0
предсказуем ли результат?
    #38537943
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вам уже намекнули что правильный ответ такой - Числа с вещественной точкой сравнивать через == нельзя Точка.
...
Рейтинг: 0 / 0
предсказуем ли результат?
    #38537946
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
redwhite90, дело в том что дробно-десятичная константа не мапиться в double и float как один
к одному. Там будет аппроксимация дробной части к наиболее близкому числу. Поэтому
само по себе присвоение уже имеет дефект точности.

Чтобы избежать дефектов сравнения договорились сравнивать как

Код: java
1.
System.out.println(abs(0.3 - 0.1+0.1+0.1) < epsilon);



Где эпсилон ты сам задаёшь как критерий точности.
...
Рейтинг: 0 / 0
предсказуем ли результат?
    #38537972
redwhite90
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
mayton, забыл_ник

я это знаю.


просто был вопрос в тесте такой...могу предположить, что и на scjp такой может быть.

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

А если нет, то оказывается тоже иногда будет true. Хочу узнать возможно ли в уме прикинуть когда true, когда false
...
Рейтинг: 0 / 0
предсказуем ли результат?
    #38537976
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В уме трудно прикинуть чему будет равно 1.0/3.0 в float, double представлении,
поэтому заниматься этим не стоит.
...
Рейтинг: 0 / 0
предсказуем ли результат?
    #38537977
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
redwhite90,

Как я унал недавно на quizful, чтобы узнать, представляется ли десятичная дробь конечной двоичной, нужно перевести ее в обычную дробь, сократить и посмотреть является ли знаменатель степенью двойки. И сама степень скажет сколько дробных разрядов надо.

0.3 = 3/10 - конечным не получается
1/10 - тоже

т.е. ни 0.3 не будет точным, ни 0.1
в итоге изза последнего разряда оно не сойдется и будет false

из примеров ниже,
0.5 = 5/10 = 1/2 -- число запишется точно
Сумма пяти 0.1 будет округлена до 0.5 скорей всего, так что true
...
Рейтинг: 0 / 0
предсказуем ли результат?
    #38537990
redwhite90
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
chabapok,

ну а 0.2 - не переводится в 2 сс, но результат true
...
Рейтинг: 0 / 0
предсказуем ли результат?
    #38538019
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
redwhite90,

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
BigDecimal delta = BigDecimal.ONE.divide(BigDecimal.TEN);         // 0.1
BigDecimal n = BigDecimal.valueOf(100);
BigDecimal result = delta.multiply(n);                            // 10.0
BigDecimal number = BigDecimal.ZERO;                              // 0.0
for (int i = 0; i < n.intValue(); i++) {
	number = number.add(delta);                               // number += 0.1;
}
System.out.println(result.equals(number));                        // true
System.out.println(result.doubleValue() == number.doubleValue()); // true
System.out.println(result.floatValue() == number.floatValue());   // true
...
Рейтинг: 0 / 0
предсказуем ли результат?
    #38538133
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
redwhite90,

0.2 = 2/10 = 1/5
5 не степень двойки, значит конечным числом не представляется

А true тут не при чем. Это уже к сложению относится - надо смотреть чего там с младшим разрядом получится. Хз как это посмотреть.
Но в тестах должно даваться то, что можно в уме предугадать. (не знаю можно ли понять тут, лично я понять не могу)
...
Рейтинг: 0 / 0
предсказуем ли результат?
    #38538170
redwhite90
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Usmanredwhite90,

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
BigDecimal delta = BigDecimal.ONE.divide(BigDecimal.TEN);         // 0.1
BigDecimal n = BigDecimal.valueOf(100);
BigDecimal result = delta.multiply(n);                            // 10.0
BigDecimal number = BigDecimal.ZERO;                              // 0.0
for (int i = 0; i < n.intValue(); i++) {
	number = number.add(delta);                               // number += 0.1;
}
System.out.println(result.equals(number));                        // true
System.out.println(result.doubleValue() == number.doubleValue()); // true
System.out.println(result.floatValue() == number.floatValue());   // true



если честно не понял, что я должен тут увидеть.
...
Рейтинг: 0 / 0
предсказуем ли результат?
    #38538171
redwhite90
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
chabapokredwhite90,

0.2 = 2/10 = 1/5
5 не степень двойки, значит конечным числом не представляется

А true тут не при чем. Это уже к сложению относится - надо смотреть чего там с младшим разрядом получится. Хз как это посмотреть.
Но в тестах должно даваться то, что можно в уме предугадать. (не знаю можно ли понять тут, лично я понять не могу)
источник вопроса

http://www.quizful.net/TestStoreAction.viewQuestion?question=UOcsHuSsfIa2#5558656655373698788
...
Рейтинг: 0 / 0
предсказуем ли результат?
    #38538179
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
redwhite90если честно не понял, что я должен тут увидеть.Увидеть разницу!
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
double delta = 1.0 / 10;
double n = 100;
double result = delta * n;
double number = 0;
for (int i = 0; i < n; i++) {
	number += delta;
}
System.out.println(result == number); // false

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
float delta = 1.0F / 10F;
float n = 100;
float result = delta * n;
float number = 0;
for (int i = 0; i < n; i++) {
	number += delta;
}
System.out.println(result == number); // false

P.S.
Хотелось донести тот факт, что BigDecimal работает с вещественными числами намного предсказуемее .
...
Рейтинг: 0 / 0
предсказуем ли результат?
    #38538369
redwhite90
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
UsmanХотелось донести тот факт, что BigDecimal работает с вещественными числами намного предсказуемее .


тяжело не согласиться
...
Рейтинг: 0 / 0
предсказуем ли результат?
    #38539219
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
redwhite90источник вопроса...

вот тут еще можно похожий вопрос посмотерть - www.quizful.net/TestStoreAction.viewQuestion?question=BM85bA43XmMK
...
Рейтинг: 0 / 0
предсказуем ли результат?
    #38540517
redwhite90
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
chabapok,

пожалуй даже сюда запостю:

авторpublic class Main {
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
 public static void main(String[] args) { 
        try { 
            String value = "29.1"; 
            System.out.println((Float.valueOf(value) + 1.0) == 30.1); 
            System.out.println((Double.valueOf(value) + 1.0) == 30.1); 
            System.out.println(Float.valueOf(value)/0); 
            System.out.println(Double.valueOf(value)/0); 
        } 
        catch (NumberFormatException ex) { 
            System.out.println("NumberFormatException"); 
        } 
        catch (ArithmeticException ex) { 
            System.out.println("ArithmeticException"); 
        } 
    } 


ответ:

1: Float.valueOf(value) дает 29.1f. Далее 29.1f приводится к double т.к. 1.0 имеет тип double (по-умолчанию все литералы с плавающей точкой имеют тип double). Получаем 29.100000381469727d. Соответственно (Float.valueOf(value) + 1.0)=30.100000381469727d. И в результате (Float.valueOf(value) + 1.0) == 30.1 равно false.
2: Аналогично п.1 только без приведения float к double, все переменные типа double. (Double.valueOf(value) + 1.0) дает 30.1d. И в результате (Double.valueOf(value) + 1.0) == 30.1 равно true.
3: Деление float на ноль не дает ArithmeticException (только деление целого типа на ноль даст ArithmeticException), для таких случаев в классе Float даже определена константа: public static final float POSITIVE_INFINITY = 1.0f / 0.0f;
Причем если заглянуть в исходники метода java.io.PrintStream#println(float), то становится ясно что float превращается в строку с помощью метода String.valueOf(float), который POSITIVE_INFINITY преобразует в "Infinity".
4: Аналогично п.3.
}

Что скажете? разве правда?

Если даже следовать его логике, то 29.1 не переводится в двоичную CC => 29.1 +1 не равно 30.1
...
Рейтинг: 0 / 0
предсказуем ли результат?
    #38540678
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
redwhite90,

для меня это такая же тайна, покрытая мраком.
Правил перевода float -> double я не нашел, но судя по личным тестам, "новые" биты заполняются рандомными значениями. Реверс-инженирингом не получается понять чего оно так работает, а документации не нашел.

причем, по всей видимости, тут java вообще не при чем, надо смотреть стандарт IEEE-754

Пока я не могу обьяснить почему оно так работает.
...
Рейтинг: 0 / 0
предсказуем ли результат?
    #38540688
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не должно быть там ничего рандомного.

Посмотрите как работает онлайн калькулятор для IEE 754 для 32-х битных вещественных чисел.
http://www.h-schmidt.net/FloatConverter/
...
Рейтинг: 0 / 0
предсказуем ли результат?
    #38540956
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У этого формата нет запрещённых комбинаций но есть маска при которой число
являеся Не-числом (Nan) двух подвидов и бесконечность (Infinity) со знаками "+" и "-"

Тоесть из 4 млрд состояний float числа небольшая часть будут иметь смысл.

И область допустимых значений на всём диапазоне - неравномерна. Тоесть
чем больше число - тем грубее идёт шаг.
...
Рейтинг: 0 / 0
25 сообщений из 54, страница 1 из 3
Форумы / Java [игнор отключен] [закрыт для гостей] / предсказуем ли результат?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]