Подозрительное поведение shl
Модератор: Модераторы
Re: Подозрительное поведение shl
Т.е. 1000000000000000000000000000000000000000000000000000000000000000 на 64-битной системе и 0000000000000000000000000000000010000000000000000000000000000000 на 32-битной?
Re: Подозрительное поведение shl
Kemet писал(а):результат будет зависеть от битности системы
x86: 1111111111111111111111111111111110000000000000000000000000000000
x86_64: 1111111111111111111111111111111110000000000000000000000000000000
Re: Подозрительное поведение shl
И добавлю ARMv6: 0000000000000000000000000000000000000000000000000000000000000000 :)
-
Kemet
- постоялец
- Сообщения: 241
- Зарегистрирован: 10.02.2010 18:28:32
- Откуда: Временно оккупированная территория
- Контактная информация:
Re: Подозрительное поведение shl
А если
Вообще, смешивать знаковые и беззнаковые в одном выражении это моветон
Код: Выделить всё
function SixtyThree: UInt64;
begin
SixtyThree := 63;
end;
var
U: UInt64;
begin
U := UInt64(1) shl SixtyThree;
Writeln(BinStr(U, 64));
end.Вообще, смешивать знаковые и беззнаковые в одном выражении это моветон
Re: Подозрительное поведение shl
С такой явной подсказкой оно работает как надо. А что, константа 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.
Ни та, ни другая не выдают того, что ожидает наивный программист (!)
Re: Подозрительное поведение shl
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. Если оно действительно так.
-
Kemet
- постоялец
- Сообщения: 241
- Зарегистрирован: 10.02.2010 18:28:32
- Откуда: Временно оккупированная территория
- Контактная информация:
Re: Подозрительное поведение shl
А какое? ))) Компилятор же не знает чего об этом думает программист, поэтому вынужден следовать определенному соглашению, например, что все числовые константы это знаковое целое.Дож писал(а):А что, константа 1 -- это знаковое?
Добавлено спустя 4 минуты 51 секунду:
Дож писал(а):Ни та, ни другая не выдают того, что ожидает наивный программист (!)
Насколько я помню, результат функции ORD - целочисленный, то есть знаковое целое
Re: Подозрительное поведение shl
Тогда почему разные результаты? И там, и там Ord :)
Re: Подозрительное поведение shl
Kemet писал(а): потому что константное выражение, а оно, вроде как, считается в 64 бит всегда
Практика показывает, что это совсем не так. Для нецелых чисел 32-ух битный компилятор засовывает константы в Extended, а 64-ехбитный - в Double. Для целых чисел подбирается тип, в который влазиет число. Но если число будет больше чем 32 бита, то компилятор всё равно тупо суёт его в 32 бита. В этом отношении очень легко нарваться на ошибку, которую будешь искать очень долго и, возможно, безуспешно...
-
Kemet
- постоялец
- Сообщения: 241
- Зарегистрирован: 10.02.2010 18:28:32
- Откуда: Временно оккупированная территория
- Контактная информация:
Re: Подозрительное поведение shl
Хз, возможно из-за того, что E это пользовательский тип, фрипаскаль обрабатывает выражение как-то иначе, нужно с Дельфи сравнитьДож писал(а):Тогда почему разные результаты? И там, и там Ord
Добавлено спустя 4 минуты 26 секунд:
Видимо, Ord( True ), в итоге преобразуется к Int64, а Ord( One ) остаётся Integer
Re: Подозрительное поведение shl
Kemet
Неправильно Вам про целые сказал.
Целые константы компилятор всегда пытается засунуть в минимально возможный тип, я только не знаю, как он там ориентируется в знаково-беззнаковых типах...
Неправильно Вам про целые сказал.
-
Kemet
- постоялец
- Сообщения: 241
- Зарегистрирован: 10.02.2010 18:28:32
- Откуда: Временно оккупированная территория
- Контактная информация:
Re: Подозрительное поведение shl
Тынц
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.
Re: Подозрительное поведение shl
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.Тынц...
У вас нет необходимых прав для просмотра вложений в этом сообщении.
-
Kemet
- постоялец
- Сообщения: 241
- Зарегистрирован: 10.02.2010 18:28:32
- Откуда: Временно оккупированная территория
- Контактная информация:
Re: Подозрительное поведение shl
Так речь идёт о константных выражениях, а не о том, сколько места занимает объявленная константа.
- Снег Север
- долгожитель
- Сообщения: 3067
- Зарегистрирован: 27.11.2007 15:14:47
- Контактная информация:
Re: Подозрительное поведение shl
Эта фигня с целыми в разной битности компилятора проявляется много где. Например, сталкивался, что при попытки конвертировать слишком большое символьное представление в integer в 32х програме дает правльно сообщение об ошибке. А в 64х программе сообщения об ошибке нет, но результат мусорный.
