cresta Лучше всего использовать тип соответствующий диапазону вычислений. Например sin (pi / 4) как будет представлен при целочисленных вычислениях??? Любой программист должен знать область определения и область значений используемых функций, исходя из этого выбирать тип данных. А если заранее неизвестна размерность или - она бесконечна где-то уже задавали вопрос как перемножить оччень большие целые числа...
> Команда test это не проверка, а арифметическое действие - пибитовое И. Т.к. флаг S всегда равен старшему биту результата, то последующее JS будет выполняться, если старший бит числа = 1. Как интерпретировать это число - это наше дало, можно его рассматривать как signed, так и unsigned. Это происходит во время компиляции. Если же необходимо проверить тип числа в runtime, то необходимо выделить ещё один (дополнительный) бит - признек тапа. Его нет в примере cresta - отсюда все проблемы. Runtime информация о типе доступна в некоторых HLL. При использовании ассемблера как правило информация о типе операндов кодируется в инструкциях их обрабатывающих. Вот ещё код для медитации: 00 00 00 00 Что это? Один DWORD или четыре BYTE?
Если уж быть совсем точным, то команда test выполняет логическую операцию И, причем затрагиваются только флаги, а операнды остаются без изменения. Этим она и "вкусна", собственно.
letopisec Вообще-то ты был прав . Наполовину только. test ecx,ecx дейчтвительно делает проверку на ноль. Если ecx = 0, то в результате будет установлен флаг ZF. Соответственно последующая JZ (или, что то же самое, JE) будет выполняться если ecx = 0. Опять же смысл здесь в том, какой(ие) именно флаг(и) анализируется после арифметический (или это логическая? я не уверен =) команды. Вот для примера ещё несколько способов проверки на 0: Код (Text): and ecx,ecx ; тоже что и тест, но результат операции сохраняется в ecx. JZ zero and ecx,-1 JZ zero or ecx,ecx JZ zero or ecx,0 JZ zero xor ecx,0 JZ zero inc ecx dec ecx JZ zero cmp ecx,0 JZ zero cmp ecx,1 JC zero sub ecx,1 JC zero add ecx,-1 JNC zero add ecx,ecx JA zero ; (ZF=0 и CF=0) not ecx inc ecx JZ zero neg ecx JNC zero 5 последних меняют регистр, но иногда это полезно. Для проверки обычно использубтся test или cmp т.к. результат этих операций не сохраняется, т.о. они быстрее.
letopisec Пожалуйста, не путай теплое и мягкое. Я говорю о числах, а не о их представлениях. 2^32-1 - это число, FFFFFFFF - его представление. У числа -1 такое же представление. Т.е. если к примеру, пользователь ввел с клавиатуры два разных числа(4294967295 и -1, которые в его представлении - отрицательное и положительное, ведь он может и не знать такого извращенства, как знаковое/беззнаковое) то я смогу определить, какое число было введено, только через подсчет количества нажатых клавиш? Больше или меньше определенного количества символов. Т.е. надо либо наблюдать процесс появления представления числа, либо переходить к большей разрядности. Обратная задача - только по представлению числа однозначно получить само число - нерешаема. Я так понял. S_T_A_S_ Наверное, правильнее сказать "как интерпретировать представление числа" Что касается кода для медитации, то в нормальном понимании это ноль. Его можно назвать двордом, 4-мя байтами или назвать носорогом, неважно. Главное, чтобы носорог вел себя как ноль, а не норовил при случае удрать в саванну.
cresta > Возможно, у меня плохо с терминологией . > Почему же это ноль? Если посмотреть страницу из браузера в hex редактроре, то будет: 30h,30h,20h,30h,30h,20h,30h,30h,20h,30h,30h imho определённо сказать что это за данные можно только в каком-то конкретном контексте. Алгоритмы всегда связанны с данными. Это фундаментальное понятие. Как Yin & Yang .
S_T_A_S_ Последовательность нулей вполне может оказаться куском файла .bmp, просматриваемого в Notepad. Файла с изображением носогора. Почему бы и нет? Хотя это уже другая история.
cresta Нет, это не другая история. Тот же .bmp файл выглядит по разному, в зависимости от программы, которой его открываем (читай: алгоритма обработки) Сами по себе абстрактные данные - это ничто.
Нет cresta, ты не прав. Я где-то вычитал что "-1" это не FFFFFFFF, а FF . и кста, FFFFFFFF - это тоже число, записаное в шеснадцатиричной системе счисления.
cresta Ну хорошо, тогда конкретно так: 1) Eсть y=(2^32-1)*sin(x), и a=(2^32-1)*cos(b).Как правильно сравнить y и a ? Для полноты картины неплохо было бы их округлить Допустим, мы так и сделали. Так как и sin и cos дают нам значения в интервале [-1;+1], следовательно, и y, и a могут принимать как положительные, так и отрицательные значения. Следовательно, они должны быть знаковыми. Однако в этом случае получится, что числа меняются в интервале -2<sup>32</sup>-1..+2<sup>32</sup>-1, то есть им требуется 33 бита. Вывод: если можно изменить формулу, меняем её (делаем 2<sup>31</sup>-1). Если нельзя - используем 64-битные операции. Если таковые отсутствуют, реализуем их программно.
letopisec То, что ты вычитал - не показатель. Посмотри на то что показывает отладчик: Код (Text): 0040120D |. B8 FFFFFFFF MOV EAX,-1 ;mov eax,4294967295 00401212 |. B8 FFFFFFFF MOV EAX,-1 ;mov eax,-1 Ясно дело, число. Его десятичный аналог 4294967295. А то, что мы видим в отладчике - это не число. Это то, как некоторое число себе представляет процессор. Имея строку B8 FFFFFFFF, нельзя однозначно ответить на вопрос: что создало эту строку: mov eax,4294967295 или mov eax,-1.
Зри в корень cresta. Для восьмиразрядного знакового числа -1 представление в дополнительном коде FF, для 16 разрядного -1 это FFFF, а для 33 разрядного 1FFFFFFFF. А то что мы видим в отладчике cresta, это именно число не надо ля-ля.
letopisec А ты возьми обычный настольный калькулятор, а ещё лучше лист бумаги и ручку, да умножь цифру 2 саму на себя 32 раза и посмотри, какое-же число получится?
Да, и ещё: подумай, какая разница между 33-мя разрядами и 33-мя битами. И когда поймешь, то будет тебе счастие.
Мужики, вам не надоело переливать из пустого в порожнее ? Вопрос то элементарный: о диапазоне однозначного представления чисел при ограниченном числе двоичных разрядов. Если мы работаем с 32-разрядными числами, то для гарантии правильного результата мы должны быть уверены в том, что в итоге арифметических операций мы не выйдем за диапазон: 1) 0..4294967295 если все числа заведомо положительные или 2) -2147483648..+2147483647 если числа могут быть и положительными и отрицательными. Причем здесь имеются в виду не только исходные числа, но и результаты операций: если мы используем вычитание положительных чисел, то результат может быть отрицательным. Иначе возможно переполнение и => неверный результат. Например: Код (Text): mov eax,4294967295 inc eax получим eax = 0 , а не 4294967296 как на калькуляторе. Не уверен - используй вещественные числа, int64 (EDX:EAX или MMX), или Int128 (XMM). Иначе жди "сюрпризов", которые вы тут столько времени мусолите.
cresta > Да, а какая между ними разница? Если число двоичное, то один бит - это один разряд. Если шестнадцатеричное - то один разряд - 4 бита. Но это в нашем "высокоуровневом" понимании происходит такое разделение. Для ALU все числа одинаковы, он работает с 33 разрядными двоичными числами (DWORD + CF). Десятичные же числа - это вообще чисто человеческая выдумка. Процессор не знает команды printf !
S_T_A_S > Ты слишком категоричен. ALU поддерживает обработку binary-coded decimal integers (BCD), упаковнных и неупакованных. Для неупакованных: один байт = одной десятичной цифре, для упакованных = двум десятичным цифрам. Вот только вопрос кто сейчас этим пользуется.
Дык пусть поддерживает. Всё равно это реализовано на базе одной схемы. Добавили цепи в сумматоре для учёта чисел больше 1010b и усё.