crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> сравнение значений
Trisch
  опции профиля:
сообщение 8.10.2012, 16:57
Сообщение #1


Активный участник
***

Группа: Участник
Сообщений: 379
Регистрация: 30.1.2012
Из: Запорожье
Пользователь №: 3169

Спасибо сказали: 24 раз(а)




Репутация:   0  


В общем есть код:
QList<QGraphicsItem*> items = graphicsView->scene()->items();

        foreach (QString str, pSet) {

            n = str.lastIndexOf("|");
            nX = str.left(n).toDouble();
            nY = str.mid(n+1).toDouble();

            number = 0;

            QList<QGraphicsItem*>::iterator its = items.begin();
            for (; its != items.end(); ++its) {
                pItem = *its;
                ox = pItem->x();
                oy = pItem->y();

                if ((ox == nX) && (oy == nY))
                    number++;
            }
                    }


в котором я сравниваю набор уникальных значений pSet, с общим набором значений QList. В итоге у меня должно отобразится количество каждого уникального значения, которые имеются в в общем наборе значений QList. Но, к сожалению, этот код некоторые значение просто не считает.
И если эти значение явно подставить в if вместо уникальных значений, то он все считает. К примеру:
if ((160 == nX) && (80 == nY))
                    number++;


А если подставить в место общих значений, то уже не считает. К примеру:
if ((ox == 160) && (oy == 80))
                    number++;


В чем может быть проблема?

Сообщение отредактировал Trisch - 8.10.2012, 16:58
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 8.10.2012, 18:48
Сообщение #2


фрилансер
******

Группа: Участник
Сообщений: 2941
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


сразу: toDouble - значит имеем дело с вещественными числами. А сравнивать вещественные числа напрямую оператором == бесполезно, результат будет неверен. Нужно задаваться точностью


bool Compare(double d1, doube d2, double acc=0.000001)
{
   //......|...... d2.......|........
   //...d1-acc  ...|.... d1+acc...

   if(d1-acc<d2 && d1+acc>d2)return true;
   return false;
}


выбирать точность можно и погибче: к примеру
acc=min(d1,d2)/1000.0


Сообщение отредактировал Алексей1153 - 8.10.2012, 18:54
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 12.10.2012, 8:03
Сообщение #3


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


тут дело не в точности, а в приоритете int-а. В операторе if если учавствуют int и double, сначала double будет усечён до int, а потом будет сравнение.
Поэтому нужно всё привести к double, а затем сравнивать. Например:
if ((double(ox) == nX) && (double(oy) == nY))
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 12.10.2012, 8:21
Сообщение #4


фрилансер
******

Группа: Участник
Сообщений: 2941
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


ну если бы всё было так просто, то люди не парились бы зря )
http://www.prog.org.ru/topic_20517_0.html
http://otvety.google.ru/otvety/thread?tid=2406ad03529eac01

что-то прокатит сравнением "в лоб", а что-то нет
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
iReset
  опции профиля:
сообщение 12.10.2012, 11:23
Сообщение #5


Участник
**

Группа: Участник
Сообщений: 178
Регистрация: 6.6.2012
Пользователь №: 3414

Спасибо сказали: 23 раз(а)




Репутация:   2  


Цитата(Litkevich Yuriy @ 12.10.2012, 9:03) *
тут дело не в точности, а в приоритете int-а. В операторе if если учавствуют int и double, сначала double будет усечён до int, а потом будет сравнение.

Что за ерунда??? С каких пор при неявных преобразованиях у нас теряется точность?? double всегда был большего приоритета.
К сожалению, из приведённого кода совершенно непонятно, какого типа сравниваемые переменные. Видно только, значения какого типа они принимают.
Ну а если они того же типа, что и значения (double в обоих случаях, ox и oy тоже double, смотрим возвращаемое значение функции QGraphicsItem::x()), то тут int вообще отсутствует.

По поводу сравнения вещественных чисел Алексей1153, безусловно, прав.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 12.10.2012, 14:25
Сообщение #6


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(iReset @ 12.10.2012, 14:23) *
double всегда был большего приоритета.
да ну, правило приоритета int со времён Си существует. Ткните носом в стандарт Си++, если это не так.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 12.10.2012, 19:02
Сообщение #7


фрилансер
******

Группа: Участник
Сообщений: 2941
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


лучше всего спросить у автора, что он хотел сравнивать ) А потом расставить явные приведения
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
iReset
  опции профиля:
сообщение 12.10.2012, 21:01
Сообщение #8


Участник
**

Группа: Участник
Сообщений: 178
Регистрация: 6.6.2012
Пользователь №: 3414

Спасибо сказали: 23 раз(а)




Репутация:   2  


Цитата(Litkevich Yuriy @ 12.10.2012, 15:25) *
Цитата(iReset @ 12.10.2012, 14:23) *
double всегда был большего приоритета.
да ну, правило приоритета int со времён Си существует. Ткните носом в стандарт Си++, если это не так.

Попробую. Только это, естественно, описано в стандарте C - ISO/IEC 9899:1999.
Описание операторов эквивалентности:
Цитата
6.5.9 Equality operators
...
Constraints
2. One of the following shall hold:
— both operands have arithmetic type;
...
Semantics
...
4. If both of the operands have arithmetic type, the usual arithmetic conversions are performed. ...

Т.е. для этих операторов действуют обычные арифметические преобразования. Смотрим их:
Цитата
6.3.1.8 Usual arithmetic conversions
1. Many operators that expect operands of arithmetic type cause conversions and yield result types in a similar way. ... This pattern is called the usual arithmetic conversions:
First, if the corresponding real type of either operand is long double, the other operand is converted, without change of type domain, to a type whose corresponding real type is long double.
Otherwise, if the corresponding real type of either operand is double, the other operand is converted, without change of type domain, to a type whose corresponding real type is double.
...
Otherwise, the integer promotions are performed on both operands...


Ну и, в принципе, это просто логично. Если бы у int приоритет был выше, то выражение
3 == 3.1
давало бы истину, что, согласитесь, немного странно.


ОФФ:

Цитата(iReset @ 12.10.2012, 12:23) *
Что за ерунда???
Я приношу свои извинения за немного резкий тон.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Trisch
  опции профиля:
сообщение 12.10.2012, 21:40
Сообщение #9


Активный участник
***

Группа: Участник
Сообщений: 379
Регистрация: 30.1.2012
Из: Запорожье
Пользователь №: 3169

Спасибо сказали: 24 раз(а)




Репутация:   0  


Цитата(Алексей1153 @ 12.10.2012, 19:02) *
лучше всего спросить у автора, что он хотел сравнивать ) А потом расставить явные приведения


Я сравнивал значения типа double

Сообщение отредактировал Trisch - 12.10.2012, 21:41
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 12.10.2012, 23:46
Сообщение #10


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Цитата(Trisch @ 13.10.2012, 0:40) *
Я сравнивал значения типа double

я не использую Qt, но справочная информация говорит, что QGraphicsItem::x() и QGraphicsItem::y() возвращают не double, а некий qreal. простое гугление по этому типу выдает обсуждение, из которого ясно, что не на всех платформах этот тип эквивалентен double, иногда он может быть float. ну а при приведении типов, естессна, происходит потеря точности и всё такое.
в частности, последний комментарий от разработчика:
Цитата
Lars Knoll added a comment - 13/Mar/12 3:57 PM

We'll keep it as it for Qt 5. double on desktop and float on embedded devices.

так что всё зависит от того, какая у тебя платформа.

ну и даже если они оба типа double, то насчёт сравнения double выше верно написали, что там нужно применять точность. а точность эта будет зависеть от самих величин. можно применять разные методы. куча методов описана тут, например.

Сообщение отредактировал Iron Bug - 13.10.2012, 0:05
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 2.3.2025, 7:13