Имя: Пароль:
 
IT
Веб-мастеринг
Сравнить long и double Java
0 yavasya
 
16.02.20
17:14
Есть лаба где надо сравнить long и double. При проверке подсказали что long сравнивать с long, long и double нужно сравнить особым образом, все остальные типы приводить к double. Вопрос следующий почему long и double нужно сравнить особым образом? К BigDecimal приводить неверно .
1 Sserj
 
16.02.20
17:23
Long.compareTo(x, y)
2 ДНН
 
16.02.20
17:24
Добавьте уже новую секцию - java
3 Sserj
 
16.02.20
17:24
Хотя просто compare(x, y)
4 yavasya
 
16.02.20
17:30
(1) не верно, оба числа должны быть лонг, а тут лонрг и дабл, ты обертку от  лонга используешь
5 yavasya
 
16.02.20
17:32
(3) просто компайр не бывает
6 Конструктор1С
 
16.02.20
17:35
(4) продвижение типов, не?

double val1 = 1.0;
long val2 = (long) val1;
7 yavasya
 
16.02.20
17:35
лонг меньше дабл, почему к его к даблу привести вообще не понятно, ошибка может произойти если long_maxvalue. Все равно не понятно как
8 yavasya
 
16.02.20
17:36
(6) это косяк сильный, привести дабл к лонг, наоборот можно
9 yavasya
 
16.02.20
17:36
(6)
double val1 = 1.5;
long val2 = (long) val1; // равно 1
10 yavasya
 
16.02.20
17:38
ДенисЧ подскажи
11 Конструктор1С
 
16.02.20
17:39
(9) это понятно, я смотрю на (1)

так как их сравнивать-то "правильно"? Мне вот совсем непонятно, почему их нужно сравнивать как-то по особенному, а не продвигать один тип к другому?

Правильно будет так

long val1 = 1;
double val2 = (double) val1;
12 Конструктор1С
 
16.02.20
17:40
"long и double нужно сравнить особым образом, все остальные типы приводить к double"

Так почему long не привести к double?
13 yavasya
 
16.02.20
17:42
(11) и я уже все перечитал, не вижу проблемы. цитата "в таком случае у тебя не сработает Long.MAX_VALUE" вот подсказка от проверяющего
14 Конструктор1С
 
16.02.20
18:03
(13) походу надо как-то через классы-обёртки сравнивать
15 Sserj
 
16.02.20
18:21
(9) double превышает long на много-много порядоков, так как внутри пишется в экспоненциальной форме (много статей в инете о представление плавающей точки на уровне железа). И соответственно у тебя может быть усечение значения.
Более правильно кстати тогда не Long.compare(x,y) брать а Dobule.compare(x,y), хотя на самом деле они оба реализуются на машинном уровне а не байткодом.
16 yavasya
 
16.02.20
18:44
(15) я в (9) показал ошибку из другого сообщения, это понятно. Проблема в том что проверяющий не сичтает что перевод в дабл правильное решение. см (13)
17 Sserj
 
16.02.20
19:10
(16) JShell:

jshell> double a = Double.valueOf(Long.MAX_VALUE)
a ==> 9.223372036854776E18

jshell> long b = Long.MAX_VALUE
b ==> 9223372036854775807

jshell> Double.compare(a, b)
$3 ==> 0
18 acht
 
16.02.20
19:17
(17) А попробуй тоже самое, но long b = Long.MAX_VALUE - 1;
19 jbond
 
16.02.20
19:32
(2) Salesforce
20 Sserj
 
16.02.20
19:54
(18) Выдаст точно то же самое:
jshell> double a = Double.valueOf(Long.MAX_VALUE - 1)
a ==> 9.223372036854776E18

jshell> long b = Long.MAX_VALUE
b ==> 9223372036854775807

jshell> Double.compare(a, b)
$3 ==> 0


Просто нужно уяснить что в Double в принципе не может храниться 9223372036854775806 (Long.MAX_VALUE - 1).
происходит потеря точности:

jshell> double d = 9223372036854775806.0
d ==> 9.223372036854776E18
21 Sserj
 
16.02.20
19:55
+(20)
jshell> Double d = 9223372036854775806.0
d ==> 9.223372036854776E18

jshell> d.longValue()
$4 ==> 9223372036854775807

jshell>
22 Sserj
 
16.02.20
20:03
+(21)
jshell> Double d = 9.223372036854775E18
d ==> 9.2233720368547748E18

jshell> d.longValue()
$14 ==> 9223372036854774784

Таким образом double может хранить ближайшие числа

9223372036854774784 и 9223372036854775807
23 yavasya
 
16.02.20
20:11
(20) напиши как правильно сравнить, пока примерно понятно
24 Sserj
 
16.02.20
20:19
(23) Так я и написал Double.compare(x,y)
То что у тебя long будет к примеру Long.MAX_VALUE - 1 оно и будет либо меньше Double.valueOf(Long.MAX_VALUE) либо больше 9223372036854774784. А между этими значениями просто double просто не может содержать значений, ему физически разрядов не хватает для такой точности.
25 yavasya
 
16.02.20
21:57
(24) большое тебе спасибо ! ты 1С ник ?
26 yavasya
 
16.02.20
22:10
(24) лонги надо сравнивать между собой, а остальные сравнивать через дабл
27 Garykom
 
17.02.20
03:46
(0) long глупо сравнивать с double у них разрядность (точность) слегка иная.
https://habr.com/ru/post/219595/
https://javarush.ru/groups/posts/2136-ustroystvo-vejshestvennihkh-chisel

Короче если по тупому то можно в long засунуть такое число, которое при переносе в double потеряет свою точность.
В то время как классические int прекрасно переносятся и сравниваются с double.

Чтобы сравнить long и double надо знать точность представления типа double на конкретной платформе и привести (округлить) значение.
28 yavasya
 
17.02.20
08:03
(27) с точки зрения теории я тебя понимаю, а как на практике это реализовать. На ссылке JavaRush предлагают использовать DigDecimal
29 yavasya
 
17.02.20
08:34
вот что получилось


    static <T extends Number, V extends Number> int compareT(T num1, V num2) {

        long l1;
        long l2;
        double d1;
        double d2;

        if (num1 instanceof Long && num2 instanceof Long) {

            l1 = num1.longValue();

            l2 = num2.longValue();

            return Long.compare(l1, l2);

        } else if ((num1 instanceof Long && num2 instanceof Double) || (num1 instanceof Double && num2 instanceof Long)) {
            // можно в long засунуть такое число, которое при переносе в double потеряет свою точность

            BigDecimal b1 = new BigDecimal("" + num1);
            
            BigDecimal b2 = new BigDecimal("" + num2);

            return b1.compareTo(b2);
          
        } else

            d1 = num1.doubleValue();
            d2 = num2.doubleValue();
            return Double.compare(d1, d2);
    }
30 Xapac
 
17.02.20
09:06
и это ваш великий джава?
31 Xapac
 
17.02.20
09:06
2 числа сравнить не может. даже паскаль умеет.
32 yavasya
 
17.02.20
09:18
(29)   static <T extends Number, V extends Number> int compare(T num1, V num2) {
33 H A D G E H O G s
 
17.02.20
11:22
Хороший язык java.
Надёжный и простой, как Швейцарские часы.
34 yavasya
 
17.02.20
11:32
(33) просто здесь сравнивается класс Number, надеюсь так не используется. Лучше типизировать без компараторов.
35 jbond
 
17.02.20
15:52
(33) - вы так говорите, как будто по ха пе лучше
36 pechkin
 
17.02.20
15:55
(35) ты что делфи же лучше всех
37 080808Ник
 
17.02.20
15:56
(35) фузина зе бэст
38 pechkin
 
17.02.20
16:01
(29) вместо преобразования через строку лучше делать
BigDecimal b1 = BigDecimal.valueOf(num1);
39 yavasya
 
17.02.20
16:18
(38) сейчас гляну
40 yavasya
 
17.02.20
16:19
(38) он так не умеет, по сути я сделал тоже самое только из строки
41 Garykom
 
17.02.20
16:21
(38) Проще floatValue() и сравнивать с long
42 pechkin
 
17.02.20
16:22
43 Бешеный заяц
 
17.02.20
16:49
(0) Equals предлогали?
44 Сияющий в темноте
 
17.02.20
20:01
так это,мантисса double, это 53 бита,а long это 64
просто,внезапно,регистр сопроцессора это 80 бит и там 64 бита на мантиссу есть,т.к. длинные целые как раз 64 бита.
но типа long double во многих языках нет.

поэтому,можно из long отрезать старшие биты,если они 0,то переводить в double и сравнивать.
если не ноль,то с первого значащего бита отсчитать 53,а оставшийся хвост сраанить с нулем,если он не ноль,то в double такого числа просто нет и можно ничего не сравнивать,если они 0,то переводим в double и срааниваем.
45 Конструктор1С
 
17.02.20
20:26
(30) в жабе ещё много чудес есть
46 Midrash
 
17.02.20
20:30
(0) читайте про приведение типов
47 Конструктор1С
 
17.02.20
20:31
Академические задачи такие академические. Кто-нибудь может мне рассказать практический смысл сей задачи?
48 Midrash
 
17.02.20
20:32
(47) просто челу лень книжки читать
49 jbond
 
18.02.20
01:41
(33)

Пункт Первый. Java самый лучший язык в мире.
Пункт второй. Если пункт первый не верен, goto Пункт Первый.
51 Конструктор1С
 
18.02.20
03:12
(48) дело не в топикстартере, а в "long и double нужно сравнить особым образом". Почему бы их не сравнить как другие числа? Типа из-за того, что на каких-то там мегавеличинах будет неточность?

9_223_372_036_854_775_807

ты только представь себе размеры. Вот если будет задача учёта всех звёзд во вселенной... ну бред же какой-то.
52 Garykom
 
18.02.20
05:17
(49) В Java нет goto. Есть только "break label;"
53 jbond
 
20.02.20
00:18
В джава можно все, и даже грабить корованы.