pow(), C++ |
1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!!
pow(), C++ |
sheka |
7.10.2011 22:44
Сообщение
#1
|
Я. Группа: Пользователи Сообщений: 809 Пол: Мужской Реальное имя: Саша Репутация: 11 |
pow() некорректно работает если используется инкремент или декремент в его параметрах.
Задание: Совершая обход так: 1 3 4 10 2 5 9 11 6 8 12 15 7 13 14 16 заполнить матрицу а такими значениями: b11b12...bnn Kod (Показать/Скрыть)
В таком исполнении pow(b[k++ / N], k % N + 1); работает так как надо (еще недавно и так не работал, но теперь почему-то работает): результат (Показать/Скрыть)
а в таком pow(b[k / N], ++k % N + 1); - нет: результат (Показать/Скрыть)
Сообщение отредактировано: sheka - 8.10.2011 0:02 |
IUnknown |
7.10.2011 22:55
Сообщение
#2
|
a.k.a. volvo877 Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: 627 |
Главное, ничего не сказал, в чем корявость, что не так, что передаешь в функцию, в конце концов, ОТКУДА эта функция, из <math.h> или из <cmath>, но
Цитата работает коряво Интересная постановка вопроса. У меня вот не работает коряво, работает как положено. Если надо - кину код... |
sheka |
8.10.2011 0:01
Сообщение
#3
|
Я. Группа: Пользователи Сообщений: 809 Пол: Мужской Реальное имя: Саша Репутация: 11 |
Исправил.
|
IUnknown |
8.10.2011 1:23
Сообщение
#4
|
a.k.a. volvo877 Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: 627 |
Ты на самом деле думаешь, что оба эти фрагмента делают одно и то же? Вынужден тебя разочаровать, это не так. Вот тебе простейший тест, доказывающий это:
1) добавляешь небольшую функцию, по имени pow, которая не только вычисляет значение xy, но еще и печатает, для каких аргументов она сработала: int pow(int x, int y) , больше в коде ничего менять не надо, тебе и так будет понятно что произойдет дальше. Итак. Запускаем с pow(b[k++ / N], k % N + 1) Результат (Показать/Скрыть)
А теперь - запускаем с pow(b[k / N], ++k % N + 1) Результат (Показать/Скрыть)
И что, ты по-прежнему считаешь, что глючит pow? Может, не надо извращаться при вычислении параметров и добиваться UB (неопределенного поведения), чего ты как раз и добился? Поведение не определено, в зависимости от компилятора, фазы Луны и погоды на Сатурне будут выдаваться разные результаты. P.S. Кстати, компилятор же предупреждает тебя, что в коде не все в порядке: In function 'int main()': Неужели это не наводит на размышления? Или опять не обращаем внимания на предупреждения? Сообщение отредактировано: IUnknown - 8.10.2011 1:31 |
TarasBer |
8.10.2011 18:27
Сообщение
#5
|
Злостный любитель Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: 62 |
Я бы вообще запретил ++ в составе сложных выражений.
-------------------- |
sheka |
8.10.2011 22:05
Сообщение
#6
|
Я. Группа: Пользователи Сообщений: 809 Пол: Мужской Реальное имя: Саша Репутация: 11 |
Хм, я как бы понимаю, что вначале значение пропустило, а поэтому потом что-то дорисовало. Но я думал что в этом виноват pow, и никак не ++.
Компилятор GNU GCC (CodeBlocks 10.05) ничего не выдает. Объясните, пожалуйста, что делает ++ ужасного. Сообщение отредактировано: sheka - 8.10.2011 22:05 |
IUnknown |
8.10.2011 22:27
Сообщение
#7
|
a.k.a. volvo877 Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: 627 |
Цитата Компилятор GNU GCC (CodeBlocks 10.05) ничего не выдает. Неправда. Зайди в Project -> Build Options, в Compiler Flags включи "Enable all compiler warnings" (которая -Wall), и пересобери проект. Можешь узнать очень много интересного Теперь по while (i < M && 0 <= j) a[i++][j--] = pow(b[k / N], (++k) % N + 1);, что будет выполнено раньше, вычисление первого параметра со старым значением k, а потом инкремент и вычисление второго параметра с новым значением, или наоборот, сначала значение k инкрементируется, и вычислится второй параметр для pow(), а потом с той, уже увеличенной k, будет вычисляться первый параметр - не может никто. Это компиляторозависимо, и, кроме всего прочего, зависит от оптимизатора, ибо в конечном счете он выбирает, в каком порядке вычислять параметры, чтоб было как можно оптимальней. А это уже неопределенное поведение со всеми вытекающими последствиями: нестабильная работа программы (ты ж сам говорил, что раньше не работало, теперь вдруг заработало, помнишь? Явный признак, что что-то не так), и предупреждение, выдаваемое компилятором. Кстати, с первым вариантом: while (i < M && 0 <= j) a[i++][j--] = pow(b[k++ / N], k % N + 1);- абсолютно та же история, побочный эффект присутствует и там, а что если сначала вычислится второй параметр, а только потом - первый? Упс... Опять перестанет работать... Для гарантированного порядка вычисления - используй временные переменные, тогда UB не будет. Кстати, разницу между префиксным и постфиксным ++ (да и -- тоже) знаешь? Сообщение отредактировано: IUnknown - 8.10.2011 22:28 |
Lapp |
9.10.2011 6:42
Сообщение
#8
|
Уникум Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: 159 |
Но я думал что в этом виноват pow, и никак не ++. Я извиняюсь, что встреваю. Просто "понравился" образ мысли, не смог удержаться )).Шека, тут виноват не ++, и не Pow(), виноват ты сам. Во всех случаях прежде всего надо подозревать себя самого. Всякий раз, когда тебе хочется написать что-то вроде "pow() некорректно работает" - вспомни, что миллионы и миллионы программистов работают и не жалуются.. )) Я согласен, ++ - это жутко хитрая штука. Я помню случай, когда я искал ошибку дня два в довольно несложном коде.. и еще несколько случаев помельче - он же не только в C/C++, он мне портил кровь и в PHP, и в Java.. Но я все равно его очень люблю и запрещать не стал бы )). P.S. Я думал, что на этом форуме, благодаря стараниям volvo/IUnknown (и не только), никто не будет вот так сразу валить на компилятор.. -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
TarasBer |
9.10.2011 13:52
Сообщение
#9
|
Злостный любитель Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: 62 |
-------------------- |
sheka |
13.10.2011 16:48
Сообщение
#10
|
Я. Группа: Пользователи Сообщений: 809 Пол: Мужской Реальное имя: Саша Репутация: 11 |
Volvo,
Цитата не определен ни порядок вычисления выражений Вычисление логических выражений по короткой схеме ???Не думал, что на http://lurkmore.ru есть что-то такое издевательски поучительное Сообщение отредактировано: sheka - 13.10.2011 16:49 |
IUnknown |
13.10.2011 17:28
Сообщение
#11
|
a.k.a. volvo877 Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: 627 |
Я не про вычисление логических выражений. Я про
int f();Какая из функций будет вызвана первой (перефразируем, какой аргумент функции test будет вычисляться сначала), f() или g()? Стандарт на этот вопрос ответа не даёт. Равно, и на вопрос, как будет вычисляться x+y-z. Сначала x+y, а потом отнимут z, или все-таки сначала y-z, а потом прибавят x (причем тут даже на скобки С++ плевал с высокой колокольни, "приоритеты операций одинаковы - как хочу, так и буду делать, тебя не спросил")... Это тоже называется "порядок не определён"... |
Текстовая версия | 27.04.2024 10:07 |