Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Маленькая задачка, с небольшим подвохом 
V
    Опции темы
nickless
Дата 22.1.2009, 00:31 (ссылка) |    (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


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

Репутация: 19
Всего: 181



Недавно наткнулся на такую задачку, возможно кому-нибудь тоже будет интересно.

Имеется C/C++ код:
Код

int foo(int x)
{
    return x != 0 && x == -x;
}


Вопрос: Может ли функция foo вернуть не 0, почему и от чего это зависит.

Если кто знает, не пишите сразу решение, пусть другие немного подумают smile 


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

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
REZiaMIX
Дата 22.1.2009, 00:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Придумал почему может , но это не то  , что тут задумано))))


--------------------
user posted image
PM MAIL   Вверх
ISergeyN
Дата 22.1.2009, 03:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



здесь что-то с нулём связано так как 
Код

int x = 0;
if( x == -x )
    cout<<"ok"<<endl;

PM MAIL Skype   Вверх
Kallikanzarid
Дата 22.1.2009, 03:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Это задача математическая (3й класс), а не на С++  smile 
x = -x => 2x = 0 => x = 0
Эрго, foo всегда будет возвращать 0, если только программа не выполняется на машине, где 0 - булева истина  smile 

Это сообщение отредактировал(а) Kallikanzarid - 22.1.2009, 03:58
PM MAIL   Вверх
nickless
Дата 22.1.2009, 04:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


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

Репутация: 19
Всего: 181



Люди, ну там же специально проверка стоит x != 0 smile 


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

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
MastEdm
Дата 22.1.2009, 11:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Master
*


Профиль
Группа: Участник
Сообщений: 178
Регистрация: 3.12.2005
Где: Москва, МГИУ

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



Может, если
Код

x = INT_MIN

потому что INT_MIN = –2,147,483,648, а INT_MAX = +2,147,483,647. Хотя зависит, наверное, от компилятора  smile 
PM MAIL   Вверх
Alek86
Дата 22.1.2009, 11:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



все банально
если x - расшарена между 2мя потоками на запись, то ф-я может вернуть и 1 smile

ЗЫ. все ж таки мы программисты, а не математики...

Добавлено через 9 минут и 19 секунд
хотя, если без приколов, то в стандарте вроде как не сказано, что INT_MIN не должен равняться INT_MAX...

Это сообщение отредактировал(а) Alek86 - 22.1.2009, 11:59


--------------------
user posted image    user posted image
PM MAIL   Вверх
vinter
Дата 22.1.2009, 12:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Цитата(Alek86 @  22.1.2009,  12:56 Найти цитируемый пост)
если x - расшарена между 2мя потоками на запись, то ф-я может вернуть и 1

каким образом? хочешь сказать поток может прервать выполнение другого потока во время проверки?


--------------------
Мой блог
PM MAIL WWW   Вверх
MAKCim
Дата 22.1.2009, 12:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(Alek86 @  22.1.2009,  11:56 Найти цитируемый пост)
если x - расшарена между 2мя потоками на запись

x передается через регистр или стек потока
race'а нет
Цитата(Alek86 @  22.1.2009,  11:56 Найти цитируемый пост)
хотя, если без приколов, то в стандарте вроде как не сказано, что INT_MIN не должен равняться INT_MAX...

а где он равняется?  smile 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
vinter
Дата 22.1.2009, 12:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



че то я не понял, почему INT_MIN == -INT_MIN?


--------------------
Мой блог
PM MAIL WWW   Вверх
Alek86
Дата 22.1.2009, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



MAKCim, про гонки точно, протупил
вопрос не в том, где такое выполняется, а в том, запрещено ли это стандартом

а вообще лично у меня все "нормальные" аргументы в пользу положительного ответа закончились.
если INT_MIN == INT_MAX  - неверно, то я выбираю ответ "нет, по стандарту C++ функция не может вернуть не 0" smile

Добавлено через 2 минуты и 21 секунду
Цитата(vinter @  22.1.2009,  12:25 Найти цитируемый пост)
хочешь сказать поток может прервать выполнение другого потока во время проверки?

да, может, причем это не стандартизировано, то есть когда ОС захочет, тогда и прервет
но тут оно не прокатит :(


--------------------
user posted image    user posted image
PM MAIL   Вверх
vinter
Дата 22.1.2009, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Alek86
Цитата(Alek86 @  22.1.2009,  13:45 Найти цитируемый пост)
если INT_MIN == INT_MAX  - неверно, то я выбираю ответ "нет, по стандарту C++ функция не может вернуть не 0"

дело не в этом INT_MIN игнорит минус, оставаясь также в значении INT_MIN


--------------------
Мой блог
PM MAIL WWW   Вверх
GoldFinch
Дата 22.1.2009, 13:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

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



задачка про баги С++ %)
PM MAIL ICQ   Вверх
xvr
Дата 22.1.2009, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(GoldFinch @ 22.1.2009,  13:27)
задачка про баги С++ %)

Это не баги а фичи, и не С++ а представления чисел в двоичном дополнительном коде  smile 
PM MAIL   Вверх
vinter
Дата 22.1.2009, 13:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



xvr, а в чем прикол? знак же дожен изменится, - должен сбросить старший разряд


--------------------
Мой блог
PM MAIL WWW   Вверх
GoldFinch
Дата 22.1.2009, 14:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

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



а ведь действительно, 
mov eax,0x80000000 / neg eax 
возвращает 0x80000000
PM MAIL ICQ   Вверх
Fazil6
Дата 22.1.2009, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



так а чего вы хотели? 
-21474836478(это 0x8000) умножить на -1 получаем 21474836478 , а это опять же 0x8000, прочитываем правильно и получаем опять  -21474836478 

Это сообщение отредактировал(а) Fazil6 - 22.1.2009, 14:22
PM MAIL   Вверх
vinter
Дата 22.1.2009, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



блин, точно. Прикольно  smile 


--------------------
Мой блог
PM MAIL WWW   Вверх
xvr
Дата 22.1.2009, 14:27 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(vinter @ 22.1.2009,  13:54)
xvr, а в чем прикол? знак же дожен изменится, - должен сбросить старший разряд

Изменение знака - это не только изменение старшего разряда. В двоично дополнительном коде изменение знака производится так: (~x)+1, т.е.
Код

0x8000 -(инверсия)-> 0x7FFF -(+1)-> 0x8000


PM MAIL   Вверх
GSasha
Дата 22.1.2009, 16:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Интересно... 
PM MAIL ICQ   Вверх
GSasha
Дата 22.1.2009, 17:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Для избежания граблей, так будет правильнее
Код

int foo(int x)
{
    __int64 _x = x;
    return ( _x != 0 ) && ( _x == -_x );
}



Это сообщение отредактировал(а) GSasha - 22.1.2009, 17:28
PM MAIL ICQ   Вверх
vinter
Дата 22.1.2009, 18:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Цитата(GSasha @  22.1.2009,  18:17 Найти цитируемый пост)
Для избежания граблей, так будет правильнее

с чего бы это?



--------------------
Мой блог
PM MAIL WWW   Вверх
GSasha
Дата 22.1.2009, 19:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(vinter @  22.1.2009,  18:11 Найти цитируемый пост)
с чего бы это?

Функция не возвратит 1 в случае передачи INT_MIN smile

PM MAIL ICQ   Вверх
vinter
Дата 22.1.2009, 19:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



GSasha, такое условие не может быть нигде применено, так что исправлять его не надо smile


--------------------
Мой блог
PM MAIL WWW   Вверх
baldina
Дата 22.1.2009, 19:49 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



GSasha, а если sizeof (int) == sizeof (__int64)  smile 
PM MAIL   Вверх
GSasha
Дата 22.1.2009, 19:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



vinter, 100% чего то увлекся увлекательной задачкой, что отошел от реальности  smile 
PM MAIL ICQ   Вверх
baldina
Дата 22.1.2009, 19:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата(vinter @ 22.1.2009,  19:42)
GSasha, такое условие не может быть нигде применено, так что исправлять его не надо smile

 smile 
PM MAIL   Вверх
nickless
Дата 22.1.2009, 19:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


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

Репутация: 19
Всего: 181



Цитата(xvr @  22.1.2009,  13:27 Найти цитируемый пост)
В двоично дополнительном коде изменение знака производится так: (~x)+1

Вот оно smile 
При передаче INT_MIN происходит знаковый overflow, т.к. (32bit)
Код

-INT_MIN == ~0x80000000 + 1 == 0x7fffffff + 1 == INT_MAX + 1 == 0x80000000 == INT_MIN


А вот тут начинаются подвохи smile 
Во-первых, если при компиляции включить проверку на overflow, этот код может вызвать ошибку исполнения.
В gcc:
Код

       -ftrapv
           This option generates traps for signed overflow on addition, subtraction, multiplication operations.

Код

% gcc foo.c -o foo -ftrapv
% ./foo
zsh: abort      ./foo


Потом вот что пишет стандарт на счет overflow (C++, C лень искать было):
Код

3.9.1 Fundamental types
4 Unsigned integers, declared unsigned, shall obey the laws of arithmetic modulo 2 n where n is the number of bits in the value representation of that particular size of integer. 41)

footnote 41)
This implies that unsigned arithmetic does not overflow because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting unsigned integer type.

5 Expressions
5 If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined, unless such an expression is a constant expression (5.19), in which case the program is ill-formed.
[Note: most existing implementations of C++ ignore integer overflows. Treatment of division by zero, forming a remainder using a zero divisor, and all floating point exceptions vary among machines, and is usually adjustable by a library function. ]


Т.е. если бы это был unsigned integer, то overflow должен работать как положено, а с signed integer - это UB, архитектурно- и компиляторозависимо.
Насколько я знаю, на маках с powerpc процессором, эта функция всегда возвращает 0 (если у кого есть, попробуйте плиз).



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

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
GSasha
Дата 22.1.2009, 19:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



 smile  и еще разок  smile 
PM MAIL ICQ   Вверх
nickless
Дата 22.1.2009, 20:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


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

Репутация: 19
Всего: 181



Цитата(vinter @  22.1.2009,  18:42 Найти цитируемый пост)
такое условие не может быть нигде применено, так что исправлять его не надо

Видел что это было использовано для проверки на overflow в сорцах питона (видел в багтрекере gcc баг по этому поводу, были проблемы как раз с powerpc, в итоге пофиксили питон).

Добавлено через 4 минуты и 20 секунд
сцылка


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

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
baldina
Дата 22.1.2009, 22:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата

в сорцах питона


Цитата

This conflicts with x<0, which means that the compiler may assume
that
  x<0 && x==-x
always yields false


там исходник на С. в С++ вероятно проще, быстрей и понятней проверить так:

Код

#include <limits>

template <typename T>
bool is_smallest (T x)
{
   return numeric_limits<T>::is_signed && x == std::numeric_limits<T>::min();
}



PM MAIL   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




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


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

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