Преобразование типов при вычислении

Вопросы программирования на Free Pascal, использования компилятора и утилит.

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

Re: Преобразование типов при вычислении

Сообщение Сквозняк » 04.08.2020 18:57:56

runewalsh писал(а): Подсказка
Hint: Mixing signed expressions and longwords gives a 64bit result[/code]
специально для подсвечивания таких случаев и сделана.


Не знаю, где так подсвечивается, может в окошке лазаруса, в консоли её нету.
Код: Выделить всё
var
   ReturnData0: byte;
   WholeData, Z1: int64; // или uint64
begin
   ReturnData0 := 230;
   Z1:=1;
   WholeData := Z1 + ReturnData0 * $1000000;
   writeln(WholeData);
   WholeData := Z1 * ReturnData0 * $1000000;
   writeln(WholeData);
end.


Не любое смешивание переменных влияет на результат, на Int64 надо именно умножать, чтобы быть уверенным что результат впишется в выделенный тип данных. Такой хак редко нужен, но там, где лень проверять диапазон всех возможных данных, он по видимому необходим.
Сквозняк
энтузиаст
 
Сообщения: 1109
Зарегистрирован: 29.06.2006 22:08:32

Re: Преобразование типов при вычислении

Сообщение runewalsh » 04.08.2020 21:33:12

Сквозняк писал(а):Не знаю, где так подсвечивается, может в окошке лазаруса, в консоли её нету.

Это будет выведено не для любых типов и платформ, а (пока?) только для 32-битного компилятора в операции (кроме вычитания?), аргументами которой являются знаковый (нативный или мельче) и беззнаковый нативный (uint32) типы. Более мелкие типы приводятся к нативным.

Например:
byte * int32 — будет вычислено как int32(byte) * int32 (внимание на знаки: беззнаковый byte приводится к знаковому типу)
byte * uint32 — вычислится как uint32(byte) * uint32 (по правилу b выше: операции, кроме вычитания, над операндами одинаковой знаковости сохраняют знаковость)
int32 * uint32 — вычислится как int64(int32) * int64(uint32) (по правилу c).

Подсказку выдаёт только последний пример, потому что её смысл в том, чтобы предупредить о генерации более медленного кода из-за неявной работы над типом, превышающим нативный. Первый пример не пикнет, потому что вылезание за размеры нативного не выполняется.

Всё это касается только 32-битного компилятора: в 64-битном нативным типом является (u)int64, а поскольку 128-битного сдвоенного нет, то и неоптимальных промежуточных приведений к нему ради корректности результата, аналогичных апкастам 32-битных значений в int64, тоже нет.
Аватара пользователя
runewalsh
энтузиаст
 
Сообщения: 578
Зарегистрирован: 27.04.2010 00:15:25

Re: Преобразование типов при вычислении

Сообщение svk12 » 04.08.2020 23:32:20

Операция присвоения имеет самый низкий приоритет.
Это значит, что
Код: Выделить всё
WholeData := Z1 + ReturnData0 * $1000000;
выполняется так:
ReturnData0:=ReturnData0 * $1000000;
Z1:=ReturnData0+Z1;
WholeData := Z1;

Делаем вывод о необходимой разрядности переменных.
svk12
постоялец
 
Сообщения: 407
Зарегистрирован: 09.06.2008 18:42:47

Пред.

Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 20

Рейтинг@Mail.ru