Модераторы: Alx, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Одинаковы ли функции? операторы сравнения 
:(
    Опции темы
zkv
Дата 2.5.2007, 01:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: нет
Всего: 92



Цитата(Ln78 @  1.5.2007,  13:23 Найти цитируемый пост)
Одинаковы ли функции:
int cmp1(int a, int b)
{
   if( a <= b ) return 0;
   return 1;
}
int cmp2(int a, int b)
{
   if( b > a ) return 1;
   return 0;

это тест на внимательность? smile Или опечатка в условии, потому что в таком виде ответ слишком очевидный: 
cmp1( 1, 2 ) != cmp2( 1, 2 );
Или "одинаковые функции" - это какой то специальный термин?
PM MAIL   Вверх
Ln78
Дата 2.5.2007, 13:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 274
Регистрация: 25.11.2006

Репутация: нет
Всего: 15



zkv, я прошу прощения, это оказался тест на внимательность для самого меня. Здесь действительно опечатка, должно быть, конечно, так:

Код

int cmp1(int a, int b)
{
   if( a <= b ) return 0;
   return 1;
}
int cmp2(int a, int b)
{
   if( a > b ) return 1;
   return 0;
}


И изменится ли ответ, если сравниваемые величины будут иметь тип double?
PM MAIL   Вверх
zkv
Дата 4.5.2007, 01:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: нет
Всего: 92



Цитата(Ln78 @  2.5.2007,  13:13 Найти цитируемый пост)
И изменится ли ответ, если сравниваемые величины будут иметь тип double? 

удалось "взломать" smile ваш пример директивами компилятору вида:
#define int MyClass 
и  перегрузкой операторов сравнения smile
Код

#include <iostream>

class MyClass
{
    int m_i;
public:
    MyClass( int i ){ m_i = i; }
    
    operator int(){ return m_i; }

    bool operator>( MyClass i )
    {
        return true;
    }
    bool operator<=( MyClass i )
    {
        return true;
    }
};

#define int MyClass 

int cmp1(int a, int b)
{
   if( a <= b ) return 0;
   return 1;
}
int cmp2(int a, int b)
{
   if( a > b ) return 1;
   return 0;
}

#undef int

int main()
{
    std::cout<<cmp1( 1, 2 );    
    std::cout<<cmp2( 1, 2 );

    std::cin.get();
        return 0;
}

все это в VC7.1, ни одного ворнинга даже не получил smile
PM MAIL   Вверх
Ln78
Дата 4.5.2007, 06:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 274
Регистрация: 25.11.2006

Репутация: нет
Всего: 15



Цитата(zkv @ 4.5.2007,  01:45)
удалось "взломать" smile ваш пример 

Это немного "нечестно"  smile , не это имелось в виду. Никаких перегруженных операторов, директив препроцессора, обычные типы int и double. Язык может быть чистый C, это неважно (в C++ ответ будет таким же).
PM MAIL   Вверх
Ln78
Дата 4.5.2007, 07:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 274
Регистрация: 25.11.2006

Репутация: нет
Всего: 15



Уточню, что когдая я говорил про тип double, я имел в виду другую пару функций:
Код

int cmpd1(double a, double b)
{
   if( a <= b ) return 0;
   return 1;
}

int cmpd2(double a, double b)
{
   if( a > b ) return 1;
   return 0;
}

PM MAIL   Вверх
The Thing
Дата 23.5.2007, 09:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 286
Регистрация: 6.9.2004

Репутация: нет
Всего: 3



Цитата(Ln78 @ 4.5.2007,  07:21)
Уточню, что когдая я говорил про тип double, я имел в виду другую пару функций:
Код

int cmpd1(double a, double b)
{
   if( a <= b ) return 0;
   return 1;
}

int cmpd2(double a, double b)
{
   if( a > b ) return 1;
   return 0;
}

Я бы ответил, что нет - неизменится! Ноч что-то мне подсказывает, что разница есть!


--------------------
Правильность работы программы зависит от двух велечин.
В нужном месте должны стоять нолик и еденичка.
PM MAIL   Вверх
The Thing
Дата 23.5.2007, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 286
Регистрация: 6.9.2004

Репутация: нет
Всего: 3



Единственное, double проверять на равно!  smile 


--------------------
Правильность работы программы зависит от двух велечин.
В нужном месте должны стоять нолик и еденичка.
PM MAIL   Вверх
Ln78
Дата 24.5.2007, 03:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 274
Регистрация: 25.11.2006

Репутация: нет
Всего: 15



The Thing, разница действительно есть (иначе зачем бы такую задачу задавал). А про 
Цитата(The Thing @  23.5.2007,  10:26 Найти цитируемый пост)
Единственное, double проверять на равно!

я не понял: что ты этим хотел сказать?
PM MAIL   Вверх
The Thing
Дата 25.5.2007, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 286
Регистрация: 6.9.2004

Репутация: нет
Всего: 3



если это не целые числа, то вряд ли они будут равны!
Этот тип данных чаще всего используется или при снятие каких-то данных с устройств или при больших вычислениях и в том и в другом случае появляется нижепредставленная проблема.

2,499999999999999999876 и 2,499999999999999999877 равны?

да вот из -за таких вотслучаев

Код

double sum = 0.0;
for(int i=0; i<10; i++)
    sum+=0.1;

if(sum == 1)
    printf(":(");
else  printf(":)");


как думаешь, что выведется? ... вот ето - ":)"


--------------------
Правильность работы программы зависит от двух велечин.
В нужном месте должны стоять нолик и еденичка.
PM MAIL   Вверх
mr.Anderson
Дата 25.5.2007, 12:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: 1
Всего: 128



В компе всегда происходит потеря точности при операциях с дробными числами, даже двойной точности double. Поэтому и сравнение на равенство не пройдет в большинстве случаев (а мож, и во всех).


--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
Ln78
Дата 25.5.2007, 14:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 274
Регистрация: 25.11.2006

Репутация: нет
Всего: 15



The Thingmr.Anderson, вы не совсем правы, особенно в отношении к данной задаче. Вообще, полезно знать, каким образом вещественные числа представляются в машине. Когда мы говорим о вещественных числах, содержащих целое число степеней двойки (возможно, и отрицательных степеней, находящихся в допустимом диапазоне), то эти числа (например, 5.0, 0.75) в машине будут представлены точно, будь то float или double. Тем более, что в данном случае мы говорим о сравнении двух вещественных чисел (как они были получены, это вопрос другой), а это не что иное, как два набора по 64 последовательности нулей и единичек. От того, что мы их в данной операции представляем вещественными числами, они ни с того ни с сего не начнут менять свои значения. Конечно, нужно понимать, что сравнение 
Код

x==0.1

строго математически не будет выполнено (хотя приближённое значение константы 0.1 тоже представляется своей последовательностью из 0 и 1, и найдётся такое значение x, которое этому равенству будет удовлетворять), и на практике чаще всего подобные сравнения лучше заменять чем-нибудь вроде
Код

fabs(x-0.1)<eps

причём eps часто намного больше, чем это вызвано машинной точностью, но и мистифицировать представление вещественных чисел в компьютере тоже не стоит: там всё - нулики и единички, и само по себе оно может меняться также как и целые числа.
PM MAIL   Вверх
Ln78
Дата 30.12.2007, 07:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 274
Регистрация: 25.11.2006

Репутация: нет
Всего: 15



Учитывая, что за прошедшее время ответ не дал никто и то, что приближается Новый год, чтобы меньше нерешённых задач перешло на следующий год, даю ответ сам. Для функций с целыми аргументами результат будет всегда одинаков. Но для аргументов с типом double существуют значения параметров, при которых функции возвращают разные значения. Дело в том, что переменная типа double, может иметь такое значение, которое означается как NaN (not a Number), и, если хотя бы одна из переменных, участвующих в любой операции сравнения, является таким «не числом», результат всегда будет false. Поэтому, например, для: 
Код

int cmpd1(double a, double b)
{
   if( a <= b ) return 0;
   return 1;
}

int cmpd2(double a, double b)
{
   if( a > b ) return 1;
   return 0;
}

int main(int argc, char *argv[])
{
   int ai[2] = {0xFFFFFFFF,0xFFFFFFFF};
   double d1 = 1.0, d2 = *( double* )ai;
   printf( "d1=%lf, d2=%lf\n", d1, d2 );
   int i1 = cmpd1( d1, d2 );
   int i2 = cmpd2( d1, d2 );
   printf( "i1=%d, i2=%d\n", i1, i2 );
   return 0;
}

имеем:

d1=1.000000, d2=-1.#QNAN0
i1=1, i2=0

Это сообщение отредактировал(а) Ln78 - 30.12.2007, 07:19
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Интересные и занимательные задачи по программированию | Следующая тема »


 




[ Время генерации скрипта: 0.0870 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.