реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> Тип данных в Кейле
demiurg_spb
сообщение Jul 12 2011, 07:02
Сообщение #16


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



К слову. Все современные компиляторы самостоятельно будут использовать сдвиг вместо деления когда это оправдано, так что (x*5)/8 совершенно равнозначно (х*5)>>3, но читается проще.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jul 12 2011, 08:48
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(demiurg_spb @ Jul 12 2011, 11:02) *
Все современные компиляторы самостоятельно будут использовать сдвиг вместо деления когда это оправдано
Возможно, но иногда удивляешся коду, который нагенерил "современный" компилятор...

Цитата(demiurg_spb @ Jul 12 2011, 11:02) *
(x*5)/8 совершенно равнозначно (х*5)>>3
А, вот тут я с Вами не согласен. Насколько я помню (поправьте, если я не прав): раставленные в выражении (x*5)/8 скобочки никак не определяют последовательность выполнения операций. Поскольку приоритеты операций * и / одинаковые, то выражение (x*5)/8 с точки зрения компилятора в соответствии со стандартом эквивалентно x*5/8 или даже x*(5/8). Компилятор вправе на этапе трансляции вычислить часть выражения, если операнды - константы. Но, поскольку 5/8 равно нулю, то можно получить результат далёкий от ожидаемого...
При вычислении выражения (х*5)>>3 последовательность вычислений однозначно определена приоритетами.
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 12 2011, 09:22
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Палыч @ Jul 12 2011, 12:48) *
Насколько я помню (поправьте, если я не прав): раставленные в выражении (x*5)/8 скобочки никак не определяют последовательность выполнения операций.

Поправляю. Вы не правы. И даже просто с позиции здравого смысла: нафиг скобки вообще нужны, если они ни на что не влияют?
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jul 12 2011, 09:33
Сообщение #19


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Проверил живьём на максимальном уровне оптимизации выражение
Код
uint32_t x;
x = (x*5)/8;
превратилось в
Код
0x08001C88 4C06      LDR      r4,[pc,#24]; @0x08001CA4
0x08001C8A 6820      LDR      r0,[r4,#0x00]
0x08001C8C EB000080  ADD      r0,r0,r0,LSL #2
0x08001C90 08C0      LSRS     r0,r0,#3
0x08001C92 6020      STR      r0,[r4,#0x00]

Всё как и ожидалось сначала умножил на 5 (хитро сложив и сдвинув), а потом поделил на 8 (сдвинув направо на 3).
Стандарта в части скобочек не могу процитировать, но полагаю что scifi близок к истине.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jul 12 2011, 09:43
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(scifi @ Jul 12 2011, 13:22) *
нафиг скобки вообще нужны, если они ни на что не влияют?
Я не утверждал, что скобки "ни на что не влияют". Например в выражении (х*5)>>3 они (скобки) очень даже "влияют". А, вот, в выражении (x*5)/8 компилятор вправе их игнорировать...
Пример попроще: выражение (х+2)-1. Как Вы думаете: компилятор сгенерирует 1) выполнение двух операций или 2) преобразует в х+(2-1) и, соответственно, вычислит на этапе трансляции (2-1) и, в конце концов, получим х+1 ?
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jul 12 2011, 09:50
Сообщение #21


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Я думаю что Вы оба правы. Когда можно упростить выражение без изменения сути, это будет сделано компилятором несомненно.
Но в примере с умножением и сдвигом никаких упрощений быть не может для целочисленных не кратных чисел.
Мне вот на ум приходит вредный совет для начинающих: не уверен в приоритетах операций - расставь скобочки.
И это правило работало всегда без исключений.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 12 2011, 09:55
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Палыч @ Jul 12 2011, 13:43) *
А, вот, в выражении (x*5)/8 компилятор вправе их игнорировать...

Ну, если мне не верите, проверьте сами. По-вашему выражение (x*5)/8 даёт результат 0 вне зависимости от значения x. Это легко проверить. Или Вы хотите сказать, что результат выражения зависит от уровня оптимизации? Тогда это вообще нонсенс. Кому нужна оптимизация, коверкающая результат простейшего арифметического выражения? Не говоря уже о том, что это просто противоречит стандарту языка Си.

Добавление:
Да, в стандарте языка указаны случаи, в которых порядок вычисления не определён. Например, порядок вычисления аргументов функции. Или операндов побитового И или ИЛИ (& или |). Но (x*5)/8 - не тот случай. Стандарт чётко описывает, что сначала идёт умножение, а потом - деление (кстати, и без скобок тоже, по правилам приоритетов операторов). Причём умножение и деление происходят в "абстрактной машине". Что там нагенерит компилятор - его дело, лишь бы результат был бы такой же, как в "абстрактной машине". Как мы видели, он может нагенерить сдвиги и сложения. Или вообще подставить константу, если результат выражения известен на этапе компиляции.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jul 12 2011, 09:56
Сообщение #23


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(demiurg_spb @ Jul 12 2011, 14:50) *
Я думаю что Вы оба правы. Когда можно упростить выражение без изменения сути, это будет сделано компилятором несомненно.

Докажите что ли на конкретном примере кода и компилятора. А так - очередной "вредный совет" или версия.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jul 12 2011, 10:03
Сообщение #24


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(GetSmart @ Jul 12 2011, 13:56) *
Докажите что ли на конкретном примере кода и компилятора. А так - очередной "вредный совет" или версия.
Для себя уже давно доказал на разных компиляторах...
Вы хотите увидеть как x=(x-1)+2 превратится в x+=1 ???


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jul 12 2011, 10:18
Сообщение #25


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(demiurg_spb @ Jul 12 2011, 15:03) *
Для себя уже давно доказал. Для разных компиляторов...

То есть какой-то компилятор может "наплевать" на скобки? Какой?

Upd.
Проверил на IAR-е.
Сложения и вычитания костант, идущие друг за другом даже за скобками он упрощает. Потому как переполнения на них не влияют. А умножения и деления нет.

Сообщение отредактировал GetSmart - Jul 12 2011, 10:27


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 12 2011, 10:27
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(GetSmart @ Jul 12 2011, 14:18) *
То есть какой-то компилятор может "наплевать" на скобки? Какой?

Как я понял, demiurg_spb и не намекает на то, что компилятор может наплевать на скобки. Напротив:
Цитата(demiurg_spb @ Jul 12 2011, 13:50) *
Когда можно упростить выражение без изменения сути, это будет сделано компилятором несомненно.

В данном случае перестановка скобок (x*5)/8 -> x*(5/8) очень даже изменяет суть, а потому компилятору не разрешена. Что мы и пытаемся объяснить Палычу.
Не соглашусь только, что компилятор применит оптимизацию "несомненно", так как видел немало тупых компиляторов.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jul 12 2011, 10:49
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(scifi @ Jul 12 2011, 13:55) *
Ну, если мне не верите, проверьте сами. По-вашему выражение (x*5)/8 даёт результат 0 вне зависимости от значения x. Это легко проверить. Или Вы хотите сказать, что результат выражения зависит от уровня оптимизации?
Нет, зависит от "уровня" трансляторописателей, вернее их понимания "духа и буквы" стандарта.

Цитата(scifi @ Jul 12 2011, 13:55) *
Стандарт чётко описывает, что сначала идёт умножение, а потом - деление (кстати, и без скобок тоже, по правилам приоритетов операторов).
Тут с Вами не соглашусь. Приоритет всех мультипликативных операций (*, /, %) одинаков.

Цитата(GetSmart @ Jul 12 2011, 14:18) *
То есть какой-то компилятор может "наплевать" на скобки?
В некоторых случаях - да, может "наплевать". Речь идёт о операциях с одинаковым приоритетом в скобках и за скобками. Нет времени искать точную формулировку в стандарте, но, по-памяти: "порядок выполнения операций может быть изменён, если это не приводит к изменению значения выражения". С учетом того, что при выполнении операций могут возникать всякие-разные "неприятности" (типа переполнения результата), то понятие "неизменный результат" становится очень расплывчатым, и тут - простор для трансляторописателей...
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jul 12 2011, 10:59
Сообщение #28


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(Палыч @ Jul 12 2011, 15:49) *
Нет времени искать точную формулировку в стандарте, но, по-памяти: "порядок выполнения операций может быть изменён, если это не приводит к изменению значения выражения".

Было такое. Но это исключительно когда нет скобок. Не выдумывайте свою интерпретацию


Цитата(Палыч @ Jul 12 2011, 15:49) *
В некоторых случаях - да, может "наплевать". Речь идёт о операциях с одинаковым приоритетом в скобках и за скобками.

Но нельзя распостранять эти некоторые случаи на все, в силу собственного незнания этих случаев. Именно это и есть уровень вредных советов. Лучше приводить дословную формулировку.

По логике, это можно делать, когда перепонения при исполнении операций не могут повлиять на результат. То есть то же, что и в школьной математике, но с учётом ограниченности (временных) переменных. Это подходит к сложениям/вычитаниям, лог операциям, но не относится к сдвигам, умнодениям/делениям.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 12 2011, 11:19
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Палыч @ Jul 12 2011, 14:49) *
Нет, зависит от "уровня" трансляторописателей, вернее их понимания "духа и буквы" стандарта.

То есть кто-то может неправильно понять стандарт и, соответвственно, написать компилятор с глюком. Спасибо за напоминание об это очевидном факте.

Цитата(Палыч @ Jul 12 2011, 14:49) *
Тут с Вами не соглашусь. Приоритет всех мультипликативных операций (*, /, %) одинаков.

Я имел в виду в данном конкретном выражении: (x*5)/8.

Цитата(Палыч @ Jul 12 2011, 14:49) *
Нет времени искать точную формулировку в стандарте, но, по-памяти: "порядок выполнения операций может быть изменён, если это не приводит к изменению значения выражения".

Нет нужды, я уже нашёл:
Цитата
The semantic descriptions in this International Standard describe the behavior of an abstract machine in which issues of optimization are irrelevant.
...
In the abstract machine, all expressions are evaluated as specified by the semantics. An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced (including any caused by calling a function or accessing a volatile object).


Цитата(Палыч @ Jul 12 2011, 14:49) *
С учетом того, что при выполнении операций могут возникать всякие-разные "неприятности" (типа переполнения результата), то понятие "неизменный результат" становится очень расплывчатым, и тут - простор для трансляторописателей...

В случае с целыми беззнаковыми числами никакой расплывчатости нет:
Цитата
A computation involving unsigned operands can never 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 type.

Не разобравшись в ситуации, не давайте вредных советов. Вдруг неокрепшие умы всерьёз воспримут.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jul 12 2011, 13:04
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(GetSmart @ Jul 12 2011, 14:59) *
исключительно когда нет скобок
Действительно - признаю: в стандарте порядок операций может быть изменён, если нет скобок (т.е. нет Primary expressions, имеющих при вычислениях наивысший приоритет). Однако стандарт и тут оставляет "лазейку": абсолютно вся оптимизация отдана на откуп компиляторописателям. Забавно, что IAR оптимизирует даже при выключенной оптимизации. Например, выражение (x+1)+(y+1) оптимизирует до x+y+2
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 28th July 2025 - 08:53
Рейтинг@Mail.ru


Страница сгенерированна за 0.01511 секунд с 7
ELECTRONIX ©2004-2016