OberonCore https://forum.oberoncore.ru/ |
|
Битовая арифметика https://forum.oberoncore.ru/viewtopic.php?f=29&t=2466 |
Страница 1 из 1 |
Автор: | Роман М. [ Воскресенье, 21 Март, 2010 17:26 ] |
Заголовок сообщения: | Битовая арифметика |
Есть два варианта процедур, возвращающих младшее слово от двойного слова. Но одна из них сбоит, а другая - нет, хотя разницы не вижу. Код: (* (* рабочая версия *)
PROCEDURE IntLow (a: LONGINT): INTEGER; VAR x: LONGINT; BEGIN x := a MOD 100000000L; RETURN SHORT(x) END IntLow;*) (* НЕрабочая версия *) PROCEDURE IntLow (a: LONGINT): INTEGER; BEGIN RETURN SHORT(a MOD 100000000L) END IntLow; PROCEDURE Test*; VAR y, z: LONGINT; x: INTEGER; BEGIN (* TEST PASSED *) z := 7FFFFFFF7FFFFFFFL; (* MAX(LONGINT) - MAX(INTEGER) - 1 *) x := IntLow(z); (* TEST FAILED *) z := 7FFFFFFF80000000L; (* MAX(LONGINT) - MAX(INTEGER) *) x := IntLow(z); END Test; |
Автор: | Валерий Лаптев [ Воскресенье, 21 Март, 2010 17:56 ] |
Заголовок сообщения: | Re: Битовая арифметика |
Дык может быть дело как раз в присваивании? Код: SHORT(a MOD 100000000L) не эквивалентно ? Код: x:= a MOD 100000000L;
SHORT(x) |
Автор: | Роман М. [ Воскресенье, 21 Март, 2010 18:04 ] |
Заголовок сообщения: | Re: Битовая арифметика |
Эквивалентны они с теоретической стороны, а на практике, как видно, не эквивалентны. Возможно, где-то отсутствуют требуемые проверки. Я что-то не хочу лезть в код ББ для выяснения. |
Автор: | Александр Шостак [ Воскресенье, 21 Март, 2010 18:08 ] |
Заголовок сообщения: | Re: Битовая арифметика |
Такое ощущение, что RETURN сразу задаёт диапазон значений в соответствии с типом, возвращаемый процедурой (INTEGER). Тогда SHORT(подвыражение) фактически уже принимает аргумент INTEGER. |
Автор: | Comdiv [ Воскресенье, 21 Март, 2010 18:26 ] |
Заголовок сообщения: | Re: Битовая арифметика |
Вообще, выпадать они должны в обоих случаях, поскольку результатом SHORT(number) должен быть тождество number, что для 80000000L невозможно (это больше чем MAX(INTEGER)). То, что первый вариант работает и возвращает отрицательное число, это лишь особенность реализации, на которую уповать не стоит. |
Автор: | Александр Шостак [ Воскресенье, 21 Март, 2010 18:53 ] |
Заголовок сообщения: | Re: Битовая арифметика |
В таком случае нужно реализовывать её через SYSTEM и ассемблеровский код. Что-то вроде POP EAX; POP EAX; RET; $58 $58 $C3 |
Автор: | Валерий Лаптев [ Воскресенье, 21 Март, 2010 20:27 ] |
Заголовок сообщения: | Re: Битовая арифметика |
Роман М. писал(а): Эквивалентны они с теоретической стороны, а на практике, как видно, не эквивалентны. Возможно, где-то отсутствуют требуемые проверки. Я что-то не хочу лезть в код ББ для выяснения. Скорее всего дело в размерах промежуточных переменных. В присваивании вы явно задаете тип промежуточной переменной как длинный. А неявно, видимо, размер равен обычному целому. |
Автор: | Александр Шостак [ Воскресенье, 21 Март, 2010 20:44 ] |
Заголовок сообщения: | Re: Битовая арифметика |
В арифметических операциях размер устанавливает тип с большим диапазоном. INT + LONGINT = LONGINT |
Автор: | AVC [ Воскресенье, 21 Март, 2010 21:37 ] |
Заголовок сообщения: | Re: Битовая арифметика |
Любопытен "заголовок" трапа: undefined real result (B9A3, 37E) Такое впечатление, что в операции 7FFFFFFF80000000H MOD 100000000L как-то используется плавающая арифметика. Обратите внимание на "экспоненту" числа 7FFFFFFF80000000H. |
Автор: | Info21 [ Воскресенье, 21 Март, 2010 22:02 ] |
Заголовок сообщения: | Re: Битовая арифметика |
AVC писал(а): Любопытен "заголовок" трапа: Так оно и есть.
undefined real result (B9A3, 37E) Такое впечатление, что в операции 7FFFFFFF80000000H MOD 100000000L как-то используется плавающая арифметика. |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |