· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.A&O —› Overflow detection

<< . 1 . 2 . 3 . >>

Посл.отвђт Сообщенiе


Дата: Июн 24, 2004 02:16:34

Тройное равно это побитовая эквивалентность
В книгах я нашел только одно значение тройного равно (помимо тождественно равно)
x тройное равно x%y (mod y), т.е. 5 ТР 2 (mod 3) или 5 равно 2 по модулю 3


Дата: Июн 24, 2004 02:39:38

Зачем искать в книгах, когда уже сказано что это.
Причём не только мной но и самим Уорреном в начале книги.
Также как сказано что если в базисе нет оператора побитовой эквивалентности но есть not и xor то можно выразить через not (a xor b). Я могу записать это и в С и математическими знаками и как принято в схемотехнике.
Что изменится то?
Посты похожи на переспрашивания какие-то.


Дата: Июн 24, 2004 02:43:02

The Svin
Не понимаю :(

Допускаю, но для понимания нужно будет:
1. Написать что-то типа введения о логике до того как начинать примеры Уоррена изучать.
2. Начать раскладывать примеры Уоррена сначала книги а не с этой главы.

Я сделаю, чуть подожди :)


Дата: Июн 24, 2004 03:34:02

Хорошо я попытаюсь разъяснить "забегая вперёд".

Прежде всего скажем, что процедура Уоррена универсальна, т.е.
а) Не зависит от присутсвия в схеме процессора флагов переполнения и займа\переноса.
б) в реальности x86 где можно определить переполнение можно определить по состоянию флага может быть и не нужна.
Он особо говорит об этом, т.е. о применимости этого варианта когда программист лишён возможности полагаться на внутреннее устройство которое само определяет наличие переполнения.

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

Пример:
Два отрицательных числа сложенные с друг другом должны дать отрицательное.
Однако сложив отрицательное 80000012h и отрицательное 80000034h мы получаем при 32х битном размере операнда
80000012h+80000034h=00000046h. Положительный результат.
Теперь обратим внимание на такой факт.

Сумма двух отрицательных чисел есть число отрицательное.
А значит знаковый бит их должен быть равен знаковому биту результата. 1 му.

Сумма двух положительных чисел есть число положительное.
Тоже значит что знаковый бит результата равен знаку операндов.

Теперь перейдём к самой формуле.
Я заменю Уорреновский знак побитовой эквивалентности с трёх горизонтальных на три вертикальных полосы.

Если c = a ||| b то в c выставлены те биты в 1 которые и в а и в b одинаковы. Неодинаковые биты в a,b выставлены в 0 в c.

"Непонятная формула Уоррена" :) для сложения:
(x ||| y) and ((x + y + c) xor x)

Что даёт по словам Уоррена эта формула?
Она Старший бит результата ставит в 1 если при сложении
x+y+c происходит переполнение, и ставит в 0 если переполнения при таком сложении нет.
Если результат этой формулы мы потом сдвинем вправо на 31
(при условии если операнд 32х разрядный) то получим 1 при переполнении и 0 при отсутвии его.

Разберём по "косточкам" саму формулу т.е. отдельно рассмотрим что делают входящие в неё выражения.

(X ||| Y) - выставит в 1 равные биты, нас же волнует частность этой операции а именно - знаковый бит. Он выставится в 1 если знаки и X и Y одинаковы. Неважно при этом являются ли оба они положительными или оба отрицательными.

(x + y + c) - это сам результат сложения трёх величин (с при этом равно 1 или 0) при этом помним, что он может быть неправильным если произошло переполнение. Мы его как раз на "правильность" и проверяем всем полным выражением.
Опять же в частности нас интересует Старший бит этого результата.

(x + y + c) xor x .
Здесь XOR используется для определения НеЭквивалентности.
Опять же нас волнует только старший бит.
Если он выставится в 1 то получается, что у X и у (X+Y+C)
разные знаки!

Теперь соединим это в одно.
Выражение (X ||| Y) & ((X + Y + C) xor X)
Даст 1 в знаковом бите если у результатов (X ||| Y) это бит будет 1 и у (X + Y + C) xor X он тоже будет 1.
В выражении X ||| Y старший бит выставится если знаки одинаковые. Но если знаки одинаковые то и у суммы должна быть одинаковыми! Выражение (X + Y + C) xor X ставит в 1 только если знаки суммы и X НеОдинаковые!
Получается что в всё выражение даёт 1 в знаковом бите в случае если оба операнда имеют один знак (оба отрицательные или оба положительные) а в сумме их появляется другой знак. Что противоречит математике и является результатом переполнения. Факт этого фиксируется
разобранным выражением в состоянии старшего бита результата выражения.
Побочным наблюдением может быть тот полезный для отметки факт, что переполнение не может возникнуть при сложении чисел с разными знаками.


Дата: Июн 24, 2004 04:11:14

Начать раскладывать примеры Уоррена сначала книги а не с этой главы.

Я по ней зайцем скачу. На всю книгу у меня времени нет.

(x + y + c) - это сам результат сложения трёх величин (с при этом равно 1 или 0) при этом помним, что он может быть неправильным если произошло переполнение.

Не понимаю, откуда взялся "с".
Не надо теории. На совершенно конкретном примере покажите мне.
Вот, положим,
int x = 0xFFFFFFFF, y = 1;
при их сложении обязательно возникает переполнение. При чем тут "с"?


Дата: Июн 24, 2004 04:24:05

Тут не принцип "зайцем" или кроликом важен.
У тебя сложности ни с этим а с тем что Уоррен предпологает некоторое знание логики и без этих знаний ты не то что "медленнее" поймёшь - ты вообще ничего не поймёш, если конечно сам не выведешь. Если конечно самостоятельное выведение этих знаний для тебя более быстрый путь, то ради бога. Но я ответил первый раз предпологая наличие таких знаний у тебя, просто пояснив что такое тройное равно, какое письмо на это ты послал, сам знаешь. Поэтому я посчитал, в разъяснении нужно вкратце дать понятия о них.

c это перенос (при сложении) или заем при вычитании.
Это нужно в случае если число состоит из нескольких (машинных) слов.


Дата: Июн 24, 2004 04:39:29

Свин, ну и тяжелый вы в общении человек :)
У меня постоянное чувство, что мы говорим на разных языках. Более 50% топа, что вы писали выше, я уже понял за сегодня. 3 часа времени чтения книги. Сначала нужной мне в данный момент времени главы, потом введения. У меня более нет времени на полноценное ознакомление с литературой. Это в Украине я мог себе позволить роскошь читать книги от корки и до корки. Сейчас методом урывков. Что схватил - то мое. Что не схватил - се ля ви.

ты вообще ничего не поймёш, если конечно сам не выведешь

Я уже многое понял. Спасибо вам и BlackMirror.
Спасибо за объяснения по формуле.
Но вопрос мой как был, так и остался.
Формула уже не непонятная. После объяснения "ТРОЙНОГО РАВНО", я уже суть схватил.

НО Я ПО-ПРЕЖНЕМУ НЕ ПОНИМАЮ, КАК ПРИВИНТИТЬ ТУДА "С"!

Не могли бы вы на практическом примере (будь-то С или ассемблер) показать мне, каким образом он используется при детекции переполнения в случае сложения двух целых чисел, знаковых или беззнаковых.


Дата: Июн 24, 2004 04:40:53

Это нужно в случае если число состоит из нескольких (машинных) слов.

Т.е. в случае сложения int/int это не учитывается?


Дата: Июн 24, 2004 04:44:50

Вот, положим,
int x = 0xFFFFFFFF, y = 1;
при их сложении обязательно возникает переполнение


Если это знаковые величины то переполнения не возникает.

Ты путаешь понятия переноса и переполнения.
F..F - это (- 1)в дополнительном коде. Результам будет 0.
Что и должно быть при -1+1=0


Дата: Июн 24, 2004 04:50:46

Э-э-э... Верно! Верно! Я ошибся. Уже устал. Пора спать. Я имею в виду unsigned int. Вы правы.


Дата: Июн 24, 2004 05:04:10 · Поправил: The Svin

Т.е. в случае сложения int/int это не учитывается?
Это неучитывается если всё число умещается в один машинный операнд. Допустим у тебя 32х разрядный операнд. Ты можешь его поместить в регистр сложить с другим и не нужно тебе никакого переноса учитывать.
А если у тебя операнд 64х или 96 разрядный?
И при этом нет никаких FPU и прочего. Т.е. максимальное машинное слово 32а бита? Тогда ты складываешь по частям с младших двойных слов большого операнда к старшим и на последнем сложении (самых старших двойных слов такого операнда) ты можешь применить вышеразобранную формулу для определения переполнения.
Пойми меня правильно, Володя, моя тяжёлость просто диктуется желанием чтоб ты получил максимальную пользу от моего ответа. Поэтому я пытаюсь насколько можно прояснить что непонятно и почему непонятно. "Почему" тут важнее на мой взгляд чем "что" потому что от непоняток с какой-то базовой вещью могут как следствия быть непонятки с сотнями других вещей. Я просто это по собственному опыту знаю, и просто пытаюсь именно не усложнить а облегчить тебе жизнь. У меня лично были проблемы и потери коллосального времени оттого что я мучался над вопросами которые возникали как следсвие непонимания какой-нить простой вещи, которую мне не разъяснили.
А вообще ты молодец.
Уоррен он ведь не учебник. Это сборник интересных фактов, там очень многое даётся без разъяснений, он единственный в таком роде по количеству содержания. Но разбираться в логике арифметики по нему нелегко.
Когда я начинал его читать я долго топтался на первой странице, дня два наверно. При этом вывел правила которые разъясняли работу примеров Уоррена но отсутсвовали у самого Уоррена. Если бы мне нужно было потом дать кому то другому понять как и почему это работает, а также (что ещё важнее) как Самому находить подобные трюки, то я бы сначала показал эти правила и на других фактах, и тогда примеры Уоррена становятся понятней чем аксиомы арифметики. Например, я разъяснял их Яну, когда ему было 6 лет, и он самостоятельно выводил подобные формулы.
Так что ещё раз повторю, что ты молодец, для меня с моими способностями такая скорость (по крайней мере смелость) скакания по Уоррену просто была немыслима такими темпами :)


Дата: Июн 24, 2004 05:24:07

Не могли бы вы на практическом примере (будь-то С или ассемблер) показать мне, каким образом он используется при детекции переполнения в случае сложения двух целых чисел, знаковых или беззнаковых.
Представим что у нас есть флаг переноса CF и операция сложения с этим флагом adc но нет флага переполнения OF чтобы зафиксировать случай переполнения (можно конечно было разобрать случай когда у нас нет и CF и ADC но это приведёт к дополнительному коду на реализацию определения переноса и сложения с переносом и утяжилит понимание примера не дав для этого понимания ничего нового)

вот у нас два операнда x и y по 64 бита каждый.
	mov eax,dword ptr x	;младшая часть x
	mov edx,dword ptr x[4]	;старшая часть x
	add eax,dword ptr y	;складываем младшие части eax - младшая часть

	mov ecx,edx		;ecx = x
	adc edx,dword ptr y[4]  ;складываем старшие части и флаг переноса
				;те самые (x + y + c)
;-----теперь мы можем попробывать определить не произошло ли переполнение--
	mov ebx,dword ptr y[4]	;ebx == y
	xor ebx,ecx		;ebx = x xor y
	not ebx			;ebx = x ||| y
	xor ecx,edx		;ecx = x xor (x + y + c)
	and ebx,ecx		;ebx = (x ||| y) & (x ^ (x + y + c))
	shr ebx,31		;ebx = 0 если переполнения нет 1 - если переполнение




Дата: Июн 24, 2004 05:28:13

Спасибо. Но комплимент сомнительный. Я бы тоже не отказался бы вдумчиво посидеть над книгой, последовательно разбираясь, что к чему. С хорошим ментором типа вас-Аркадия-Рельфа-Дмита... Но, увы...
"Никто не властен над судьбою, я рождена быть королевой и рождена не быть с тобою" :)


Дата: Июн 24, 2004 05:34:22

The Svin

adc edx,dword ptr y[4]

Да, но это предполагает наличие на машине средств, позволяющих детектить перенос. Вы используете ADC (x+y+c)... А если бы его не было?

И последняя просьба. Чуть подробнее по
	and ebx,ecx		;ebx = (x ||| y) & (x ^ (x + y + c))
	shr ebx,31		;ebx = 0 если переполнения нет 1 - если переполнение


Интервал значений ebx?


Дата: Июн 24, 2004 07:18:50

А если бы его не было?
Тогда нужно было бы функцию писать для вычисления переноса и потом только складывать. Тебе такую именно функцию нужно было? Сильно зависит от того чем распологает машина.
Какие операции, какие флаги. Это работа с левыми битами,
она очень неудобна. Случай когда биты одинаковые в операндах простой - CF будет равен значению старшего бита.
if ((x ||| y) shr 31)
  CF = x shr 31
endif


Если неодинаковые (if (x xor y shr 31)) - простого решения я не знаю. В сумматорах на каждый гейт приходится делать.
У Петзольда описано хорошо, у меня лучше объяснить не получится. Если CF нет но есть ZF и сдвиги то можно разложить как:
1. Проверим на совпадение:
if (a xor b) shr 31 ZF? ;старшие биты совпадают
  CF = a shr 31 ;50% случаев отслеживается сразу здесь
else ;старшие биты несовпадают
 c = ((a shr 1) + (b shr 1)) ;выдавливаем CF в старший бит
 if c and 8000000h не ZF
    CF = 1 ;или CF = c shr 31
    else
    CF = (c + (a and b and 1)) shr 31 ;учитываем последний
 endif
endif

Неуверен, что это лучшее решение. Просто пример как можно вычислить CF.

Интервал значений ebx?
Интервал это диапазон?
после shr ebx,31 будет 1 или 0. т.е. старший бит ebx переместится в младший а остальные обнулятся.

До этого нас волнует не диапозон, а значение старшего бита в ebx - он будет равен одному если произошло переполнение - т.е. когда знаки x и y (старшие биты) совпадают а знак суммы с ними не совпадает.

<< . 1 . 2 . 3 . >>


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.164