Deutsch
Germany.ruФорумы → Архив Досок→ Программирование

float в java

1733  1 2 все
kashej постоялец16.05.08 10:15
kashej
16.05.08 10:15 
Люди, в общем имеется следующий код:
float f1 = Float.MAX_VALUE;
float f2 = f1 - 1e30f;
System.out.println(f1==f2);
А теперь вопрос, почему последнее выражение выдает true? Просьба не закидывать камнями На яве програмлю уже давно, но с таким еще не приходилось сталкиваться...
Что тут за трюк? Буду рад любой информации.
http://denis-aristov.ucoz.com
#1 
  digital.pilot коренной житель16.05.08 11:08
digital.pilot
NEW 16.05.08 11:08 
в ответ kashej 16.05.08 10:15
видимо, потому, что float - тип с плавающей точкой и потому неточный. У максимального флоута порядок 10^38, так что твое вычитание числа порядка 10^30 ему как слону дробина.
#2 
  Chipolino свой человек16.05.08 15:41
NEW 16.05.08 15:41 
в ответ kashej 16.05.08 10:15
Дело не в яве .
Числа с плавающей точкой так не сравниваются.
#3 
Murr коренной житель17.05.08 12:03
Murr
NEW 17.05.08 12:03 
в ответ Chipolino 16.05.08 15:41
Числа с плавающей точкой так не сравниваются.
-----
А подумать? У человека как раз вопрос - Почему они равны? - а не то, что сравнение должно выполняться по-другому.
#4 
Murr коренной житель17.05.08 12:11
Murr
NEW 17.05.08 12:11 
в ответ kashej 16.05.08 10:15
На яве програмлю уже давно, но с таким еще не приходилось сталкиваться...
-----
А это и не Жаба. Это - float сам по себе.
Хранение float'а - {порядок} {нормализованная мантиса}. Перед сложением и вычитанием мантиса денормализуется до сравнивания порядков. В твоем случае - остаток в значимых разрядах мантисы будет нулем и вычитание ничего не изменит.
#5 
Murr коренной житель17.05.08 12:19
Murr
NEW 17.05.08 12:19 
в ответ digital.pilot 16.05.08 11:08
У максимального флоута порядок 10^38, так что твое вычитание числа порядка 10^30 ему как слону дробина.
-----
Хммм... Сейчас уже не помню, но где-то видел не 10^38, а что-то побольше... 10^308, если не ошибаюсь.
Бо, разница 10^8 - восемь значащих (десятичных) цифр - не такая большая и должна бы все же давать эффект при вычитании.
Вообщем, надо смотреть доки на Жабу по деталям реализации float'a.
#6 
  femidav прохожий17.05.08 14:05
NEW 17.05.08 14:05 
в ответ Murr 17.05.08 12:19
Сейчас уже не помню, но где-то видел не 10^38, а что-то побольше... 10^308, если не ошибаюсь.
Это double, а не float.
#7 
Murr коренной житель17.05.08 15:51
Murr
NEW 17.05.08 15:51 
в ответ femidav 17.05.08 14:05
Это double, а не float.
-----
Возможно. Именно по-этому и написал, что надо смотреть доки.
#8 
  Chipolino свой человек17.05.08 15:55
NEW 17.05.08 15:55 
в ответ Murr 17.05.08 12:03
Иди спать девачко
#9 
kashej постоялец17.05.08 16:13
kashej
NEW 17.05.08 16:13 
в ответ Chipolino 17.05.08 15:55
На последнего...
Просто дело в том, что мне нужно написать функцию, которая ожидает некоторое время определенное значение числа с плавающей точкой. При том это значение может находится в определенном интервале. Короче прототип функции такой:
boolean waitValue(float standard, long timeout, float tolerance);
Если значение вдруг оказывается между standard-tolerance и standard+tolerance то функция возвращает TRUE
Т.е. по сути пользователя ничего не сдерживает установить standard Float.MAX_VALUE. Тогда верхняя планка так и останется Float.MAX_VALUE, но а нижняя должна быть меньше. Вот тут-то я и удивился, когда отнял от standard tolerance а разницы как-будто и нет.
http://denis-aristov.ucoz.com
#10 
Murr коренной житель17.05.08 20:23
Murr
NEW 17.05.08 20:23 
в ответ kashej 17.05.08 16:13
отнял от standard tolerance
-----
А вот это уже то, об чем писал Чиполино - abs(Standard - Value) < tolerance
И подстрахуйся на предмет переполнения при вычитании.
#11 
AlexNek коренной житель22.05.08 12:24
AlexNek
NEW 22.05.08 12:24 
в ответ kashej 17.05.08 16:13
при флоате важно как диапазон представления чисел, так и количество значащих разрядов.
Если диапазон
float 32 bit java.lang.Float +/-1,4E-45 ... +/-3,4E+38
double 64 bit java.lang.Double +/-4,9E-324 ... +/-1,7E+308
http://de.wikipedia.org/wiki/IEEE_754#Zahlenformate_und_andere_Festlegungen_des_IEEE_754-Standards
In float, 24 bits are allocated for a. Thus the largest integer that can be exactly stored is 2^0 + 2^1 + ... + 2^23 = (2^24)−1 = 16,777,215
То бишь 8 значащих цифр после запятой. Так вот толерансе не должно быть тогда меньше чем 0.0000 0001
#12 
  Chipolino свой человек22.05.08 19:05
NEW 22.05.08 19:05 
в ответ AlexNek 22.05.08 12:24
Для этого в плюсовой stdlib имеется numeric_limits<T>::epsilon , что-нибудь подобное в джаве должно быть .
#13 
AlexNek коренной житель22.05.08 21:27
AlexNek
NEW 22.05.08 21:27 
в ответ Chipolino 22.05.08 19:05
Да я на яве не пишу, так только знакомым студентам иногда помогаю.
#14 
kashej постоялец26.05.08 17:28
kashej
NEW 26.05.08 17:28 
в ответ AlexNek 22.05.08 21:27
Сравнить два флоата - не проблема. Нужно просто конвертировать оба числа в байтовые массивы, а потом сравнить эти массивы. Но вот как определить какое число > или < или же <= или >=.
Может кто-нибудь знает библиотеку, которая предоставляет эти функции?
http://denis-aristov.ucoz.com
#15 
katran76 старожил26.05.08 18:24
NEW 26.05.08 18:24 
в ответ kashej 26.05.08 17:28
уже ж обьяснили вроде что "float" напрямую (a==b) не сравниваются!!!
вообще!!!
НИКОГДА!!!!
#16 
AlexNek коренной житель26.05.08 18:53
AlexNek
NEW 26.05.08 18:53 
в ответ kashej 26.05.08 17:28
В ответ на:
Сравнить два флоата - не проблема. Нужно просто конвертировать оба числа в байтовые массивы, а потом сравнить эти массивы.

самое плохое решение которое можно придумать. Перечитай еще раз ссылки и поиграйтся с разными числами.
Коротко, вещественные числа считаются равными если они отличаются на значение меньшее заданной точности. При этом заданная точность не может быть меньше реально представленной. Не путать точность и диапазон представляемых чисел!
#17 
kashej постоялец26.05.08 21:07
kashej
NEW 26.05.08 21:07 
в ответ katran76 26.05.08 18:24
Да я в курсе вообще-то, что в яве нет перегрузки операторов имел ввиду другое, жаль что ты не понял
http://denis-aristov.ucoz.com
#18 
katran76 старожил26.05.08 21:13
NEW 26.05.08 21:13 
в ответ kashej 26.05.08 21:07
я не про яву и не про операторы, я про компьютеры
жаль что ты не понял :(
#19 
Murr коренной житель27.05.08 13:26
Murr
NEW 27.05.08 13:26 
в ответ kashej 26.05.08 17:28
Нужно просто конвертировать оба числа в байтовые массивы, а потом сравнить эти массивы.
-----
??? - Ну и что же ты получишь, сравнивая 1.0*10^0 и 0.1*10^1?
P.S. К понимающим в чем именно проблемма просьба не подсказывать.
Но вот как определить какое число > или < или же <= или >=.
------
??? - указанные операторы кто-то запретил? Или они не работают с вещественными типами?
Если все определено, то надо искать проблему в пользующем...
#20 
kashej постоялец29.05.08 11:02
kashej
NEW 29.05.08 11:02 
в ответ Murr 27.05.08 13:26
Странно, но следующий код работает тоже не так, как я ожидал.
double d1 = Double.MAX_VALUE;
double d2 = d1-0.1;
long lon1 = Double.doubleToLongBits(d1);
long lon2 = Double.doubleToLongBits(d2);
System.out.println(lon1 == lon2);
Последнее выражение возвращает TRUE. Я то думал, что раз битовые представления d1 и d2 отличаются, то это должно отразиться и на значениях lon1 и lon2.
http://denis-aristov.ucoz.com
#21 
Murr коренной житель29.05.08 11:08
Murr
NEW 29.05.08 11:08 
в ответ kashej 29.05.08 11:02
Все то же самое, об чем тебе уже не раз писали в разной форме.
Разберись с тем, как хранится float...
#22 
kashej постоялец29.05.08 11:11
kashej
NEW 29.05.08 11:11 
в ответ Murr 29.05.08 11:08
Так в том то и дело, что времени на разбор нет. Хотелось бы подходящую библиотеку где-нибудь взять...
http://denis-aristov.ucoz.com
#23 
katran76 старожил29.05.08 11:38
NEW 29.05.08 11:38 
в ответ kashej 29.05.08 11:11
Ладно, сжалюсь
Твоя проблема в том что ты отнимаешь от первого числа второе второе меньше чем точность представления первого.
Приведу пример:
a=1.2345
b=0.000001
Числа при этом имеют определённую точность представления (float, ,double, ...)
Если эта точность к примеру три знака, то грубо говоря ВСЕ ЧИСЛА от 1.234 до 1.236 представлены в памяти компа ОДИНАКОВО как 1.235
Именно поэтому при вычитании числа которое меньше точности представления первое число НЕ МЕНЯЕТСЯ.
На самом деле всё немного сложнее - там двоичное представление и степень двойки.
Но принцип не меняется - каждый тип с плавающей точкой имеет кроме границ (максимальное число
представимое этим типом) ещё и точность представления (типа число знаков после запятой).
Так понятней?
#24 
Murr коренной житель29.05.08 11:53
Murr
NEW 29.05.08 11:53 
в ответ kashej 29.05.08 11:11
Хотелось бы подходящую библиотеку где-нибудь взять...
-----
Хммм... Ну это врядли... Если только не адаптируешь один из моих курсовиков - там как раз был имплементирован эмулятор четырех операций над псевдо-флоат с переменным размером... Правда для этого придется освоить Фортран-4 для СМ-1...
#25 
  digital.pilot коренной житель29.05.08 11:56
digital.pilot
NEW 29.05.08 11:56 
в ответ katran76 29.05.08 11:38
я эту мысль пытался до автора еще 2 недели назад донести... но, видимо, ява-программисты - очень занятой народ, им не до таких пустяков...
#26 
AlexOtt постоялец29.05.08 11:59
AlexOtt
NEW 29.05.08 11:59 
в ответ Murr 29.05.08 11:53
надо лишь взять что-то типа GMP - http://gmplib.org/
#27 
Murr коренной житель29.05.08 12:06
Murr
NEW 29.05.08 12:06 
в ответ katran76 29.05.08 11:38
Если эта точность к примеру три знака, то грубо говоря ВСЕ ЧИСЛА от 1.234 до 1.236 представлены в памяти компа ОДИНАКОВО как 1.235
-----
Вообще-то ТРИ знака это 1.23
На самом деле всё немного сложнее
-----
Да, float-числа хранятся в нормализованном виде - т.е. мантиса 0.123 и порядок 1 (10^1)
Кроме этого, во многих системах учитывается, что старший разряд нормальзованной мантисы всегда единца (двоичная) и потому он опускается.
Кроме этого - описанное представление - не единственно возможное. В Коболе и ПЛ/1 используются типы DECIMAL(?) весьма похожие на float, но имеющие принципиально иное представление - упакованных или распакованный двоично-десятичный код. Мало того, так еще и имплементация этих децималов в разных системах отличается...
#28 
katran76 старожил29.05.08 12:32
NEW 29.05.08 12:32 
в ответ Murr 29.05.08 12:06
вообще то точность измеряется числом значащих знаков после запятой в нормализованном представлении.
Так что 1.234=1.234*10^1 это всё-таки ТРИ
В ответ на:
Да, float-числа хранятся в нормализованном виде - т.е. мантиса 0.123 и порядок 1 (10^1)

По стандарту (если я его правильно помню) числа (как мантисса так и порядок) хранится в двоичном виде, т.е. не 0.125 а что то-типа
десятичное 0.125 = 2^(-3) = двоичное 0.001= двоичное нормализованное 1.0*2(-3)
Я поэтому и написал что на самом деле всё "немного сложнее"
Однако к вопросу автора это имеет отдалённое отношение...
Главное для него - точность нормализованного представления
#29 
Murr коренной житель29.05.08 12:40
Murr
NEW 29.05.08 12:40 
в ответ AlexOtt 29.05.08 11:59
Имею СВОЕ!!! :)
#30 
Murr коренной житель29.05.08 12:54
Murr
NEW 29.05.08 12:54 
в ответ katran76 29.05.08 12:32
в нормализованном представлении.
-----
В нормализованном представлении перед точкой нет значащих цифр - там только ноль, и в том же нормализованном предствлении цифирька после точки - не ноль. Таково, понимаешь, нормализованное представление.
Так что 1.234=1.234*10^1 это всё-таки ТРИ
-----
Четыре. Кроме этого - 1.234*10^1 = 12.34 - умножение на порядок надо реально выполнять...
По стандарту
-----
По какому из стандартов? И как этот стандарт учитывает наличие арифметических со-процессоров берущих на себя операции с флоат-типами... при двух условиях - первое - что он установлен в системе, второе - что софт знает как его использовать...
Вообщем - не заморачивайся - определяется фактической реализацией в конкретном трансляторе. Обычно опирается на аппаратные особенности системы, но может и эмулироваться.
Главное для него - точность нормализованного представления
-----
Не только. Еще существенно как именно производится операция - с денормализацией (сложение и вычитание) мантисы или без (умножение, деление, степени)... Будет понимать как это хранится и как производится операция - не будет задавать смешных вопросов... и не на чем нам будет флудераствовать...
#31 
AlexOtt постоялец29.05.08 13:12
AlexOtt
NEW 29.05.08 13:12 
в ответ Murr 29.05.08 12:40
на HP-UX v.10.20 запустится?
#32 
Murr коренной житель29.05.08 14:32
Murr
NEW 29.05.08 14:32 
в ответ AlexOtt 29.05.08 13:12
на HP-UX v.10.20 запустится?
-----
А там Фортран-4 имеется? :)
#33 
AlexOtt постоялец29.05.08 14:57
AlexOtt
NEW 29.05.08 14:57 
в ответ Murr 29.05.08 14:32
а где сейчас СМ можно взять? точнее я знаю где ее можно найти, но боюсь, что мне ее не дадут запустить
#34 
Murr коренной житель29.05.08 15:24
Murr
NEW 29.05.08 15:24 
в ответ AlexOtt 29.05.08 14:57
а где сейчас СМ можно взять?
-----
Взять, скорее всего, не дадут - там порядка двух унций золота на разъемах...
А так... хммм... на производственной оборонке, в АСУ ТП, вполне может быть...
Заодно - СМ-1 - это не линия PDP-11, а вполне самостоятельная наработка...
#35 
AlexOtt постоялец29.05.08 16:34
AlexOtt
NEW 29.05.08 16:34 
в ответ Murr 29.05.08 15:24
где они до сих пор работают я прекрасно знаю - я в свое время на практически всей линейке успел поработать
#36 
1 2 все