Подозрительное поведение shl

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

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

Re: Подозрительное поведение shl

Сообщение Дож » 18.04.2019 11:07:04

Т.е. 1000000000000000000000000000000000000000000000000000000000000000 на 64-битной системе и 0000000000000000000000000000000010000000000000000000000000000000 на 32-битной?
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 804
Зарегистрирован: 12.10.2008 16:14:47

Re: Подозрительное поведение shl

Сообщение iskander » 18.04.2019 11:08:22

Kemet писал(а):результат будет зависеть от битности системы

x86: 1111111111111111111111111111111110000000000000000000000000000000
x86_64: 1111111111111111111111111111111110000000000000000000000000000000
:?
iskander
постоялец
 
Сообщения: 195
Зарегистрирован: 08.01.2012 18:43:34

Re: Подозрительное поведение shl

Сообщение Дож » 18.04.2019 11:09:17

И добавлю ARMv6: 0000000000000000000000000000000000000000000000000000000000000000 :)
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 804
Зарегистрирован: 12.10.2008 16:14:47

Re: Подозрительное поведение shl

Сообщение Kemet » 18.04.2019 11:20:15

А если
Код: Выделить всё
  function SixtyThree: UInt64;
  begin
    SixtyThree := 63;
  end;
var
  U: UInt64;
begin
  U := UInt64(1) shl SixtyThree;
  Writeln(BinStr(U, 64));
end.

Вообще, смешивать знаковые и беззнаковые в одном выражении это моветон
Kemet
постоялец
 
Сообщения: 241
Зарегистрирован: 10.02.2010 19:28:32
Откуда: Временно оккупированная территория

Re: Подозрительное поведение shl

Сообщение Дож » 18.04.2019 11:28:47

С такой явной подсказкой оно работает как надо. А что, константа 1 -- это знаковое?

Проблема в том, что выражения бывают довольно сложные, в которых непонятно знаковое ли там число или нет. Например, следующие две программы у меня выдают разные результаты:
Код: Выделить всё
  function SixtyThree: UInt64;
  begin
    SixtyThree := 63;
  end;
var
  U: UInt64;
begin
  U := Ord(True) shl SixtyThree;
  Writeln(BinStr(U, 64));
end.

Код: Выделить всё
type
  E = (Zero = 0, One = 1);
  function SixtyThree: UInt64;
  begin
    SixtyThree := 63;
  end;
var
  U: UInt64;
begin
  U := Ord(One) shl SixtyThree;
  Writeln(BinStr(U, 64));
end.

Ни та, ни другая не выдают того, что ожидает наивный программист (!)
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 804
Зарегистрирован: 12.10.2008 16:14:47

Re: Подозрительное поведение shl

Сообщение SSerge » 18.04.2019 11:32:27

iskander писал(а):PS

RAD Studio 10.3 Rio писал(а):
Note that the value of y is interpreted modulo the size of the type of x.
Thus for example, if x is an integer, x shl 40 is interpreted as x shl 8 because an integer is 32 bits and 40 mod 32 is 8.


Вот кстати, хреново, что сие описание есть в Ras Studio, но поведение нисколько не документировано в документации fpc. Если оно действительно так.
SSerge
энтузиаст
 
Сообщения: 866
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Re: Подозрительное поведение shl

Сообщение Kemet » 18.04.2019 11:36:34

Дож писал(а):А что, константа 1 -- это знаковое?
А какое? ))) Компилятор же не знает чего об этом думает программист, поэтому вынужден следовать определенному соглашению, например, что все числовые константы это знаковое целое.

Добавлено спустя 4 минуты 51 секунду:
Дож писал(а):Ни та, ни другая не выдают того, что ожидает наивный программист (!)

Насколько я помню, результат функции ORD - целочисленный, то есть знаковое целое
Kemet
постоялец
 
Сообщения: 241
Зарегистрирован: 10.02.2010 19:28:32
Откуда: Временно оккупированная территория

Re: Подозрительное поведение shl

Сообщение Дож » 18.04.2019 11:43:51

Тогда почему разные результаты? И там, и там Ord :)
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 804
Зарегистрирован: 12.10.2008 16:14:47

Re: Подозрительное поведение shl

Сообщение Vadim » 18.04.2019 11:47:40

Kemet писал(а): потому что константное выражение, а оно, вроде как, считается в 64 бит всегда

Практика показывает, что это совсем не так. Для нецелых чисел 32-ух битный компилятор засовывает константы в Extended, а 64-ехбитный - в Double. Для целых чисел подбирается тип, в который влазиет число. Но если число будет больше чем 32 бита, то компилятор всё равно тупо суёт его в 32 бита. В этом отношении очень легко нарваться на ошибку, которую будешь искать очень долго и, возможно, безуспешно... ;-)
Vadim
долгожитель
 
Сообщения: 3698
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Подозрительное поведение shl

Сообщение Kemet » 18.04.2019 12:00:37

Дож писал(а):Тогда почему разные результаты? И там, и там Ord :)
Хз, возможно из-за того, что E это пользовательский тип, фрипаскаль обрабатывает выражение как-то иначе, нужно с Дельфи сравнить

Добавлено спустя 4 минуты 26 секунд:
Видимо, Ord( True ), в итоге преобразуется к Int64, а Ord( One ) остаётся Integer
Kemet
постоялец
 
Сообщения: 241
Зарегистрирован: 10.02.2010 19:28:32
Откуда: Временно оккупированная территория

Re: Подозрительное поведение shl

Сообщение Vadim » 18.04.2019 12:11:35

Kemet
Неправильно Вам про целые сказал. :-) Целые константы компилятор всегда пытается засунуть в минимально возможный тип, я только не знаю, как он там ориентируется в знаково-беззнаковых типах...
Vadim
долгожитель
 
Сообщения: 3698
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Подозрительное поведение shl

Сообщение Kemet » 18.04.2019 12:36:29

Тынц
FPC evaluates constant expressions always using 64 bit arithmetic in all modes, and has done so since the moment it supported 64 bit arithmetic. If you use WriteLn(int64(i) shr 32);, you'll also get 0 in the second case. Changing that would break backwards FPC compatibility. It also wouldn't surprise me if Delphi XE3 would give the same output as FPC.
Kemet
постоялец
 
Сообщения: 241
Зарегистрирован: 10.02.2010 19:28:32
Откуда: Временно оккупированная территория

Re: Подозрительное поведение shl

Сообщение Vadim » 18.04.2019 12:47:44

Kemet
Код: Выделить всё
Const
  c1 = 22;
  c2 = 33.33;
  c3 = 2200000000;
  c4 = 9200000000000000;
Begin
  WriteLn(sizeof(c1));
  WriteLn(sizeof(c2));
  WriteLn(sizeof(c3));
  WriteLn(sizeof(c4));
End.

Тынц... ;-)
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Vadim
долгожитель
 
Сообщения: 3698
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Подозрительное поведение shl

Сообщение Kemet » 18.04.2019 12:56:20

Так речь идёт о константных выражениях, а не о том, сколько места занимает объявленная константа.
Kemet
постоялец
 
Сообщения: 241
Зарегистрирован: 10.02.2010 19:28:32
Откуда: Временно оккупированная территория

Re: Подозрительное поведение shl

Сообщение Снег Север » 18.04.2019 14:03:15

Эта фигня с целыми в разной битности компилятора проявляется много где. Например, сталкивался, что при попытки конвертировать слишком большое символьное представление в integer в 32х програме дает правльно сообщение об ошибке. А в 64х программе сообщения об ошибке нет, но результат мусорный.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2130
Зарегистрирован: 27.11.2007 16:14:47

Пред.След.

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

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

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

Рейтинг@Mail.ru