Ноябрь 2006 года. Над землей бушует Смыф, бессмысленный и беспощадный. Великий и ужасный Д.Хман обращается к А.Гофману с посланием: ----------------------------------------------------------------------- Ты вроде когда-то шарил в компах(в железной их части). Так вот мне надо проконсультироваться с тобой(подискутировать) по нес-ким вопросам, если ты не против, конечно... 1. В Pascal`е (как в принцинипе везде) у чисел с плавающей запя- той диапазон выражается как a*10^-b..c*10^-d, а точность - как кол-во значащих чисел мантис(с)ы, но не точно, а через дефис, например 11-12 или 7-8. Вопрос. А где отрицательные числа?(они ведь на самом деле есть?) Почему точность задана отрезком(как она считается?) 2. Представим себе такую картину: ТЫ на паре программирования пи- шешь программу на pascal а препод(аватель) тебя и спрашивает -А введи-ка (в программу типа факториала) число 123456789 -? .-Ты вводишь и выскакивает ошибка. Ты изменяешь тип переменных с real на extnded, включаешь режим использования сопроцессора 87 и эмуляции(в Borland Pascal for Windows эмуляцию включить нельзя, но об этом далее) и всё работает. -А что такое эмуляция? -.Ты ей (сторогой, но очень соблазниельной несмотря на возраст учительнице) объясняешь и она вроди бы успокаивается, но через десять секунд: -А как работает эмуляция? -Ты ей пытаешься объяснить, что, дескать, процессор "ручками" де- лает то же, что и сопроцессор, но медленнее, поэтому эмуляция - это НЕ круто. -А почему сопроцессор, собственно говоря, работает быстрее? -.Ты подсознанием знаешь, что так задумано,а если иначе,то зачем тогда вообще нужен мат. сопроцессор? -Ну?(а учительница шарящая и очень дотошная) -.Вроде выполняет всё то же, частоты вроди бы одинаковые... -А где одна и та же программа(что-нибудь вычисляющая, то есть только текстовый вывод) выполняется быстрее: в досе или в Вин- довсе(в смысле скомпилирована под 16-bit windows application и запущена в мастдае)? -А в виндовсе процессы другие есть, да и вообще она, глупая, приоритты дурацкие криво расставляет. -В ДОСЕ? Что думаешь? Как объяснить, что сопроцессор работает быстрее(обилие техничес- ких терминов приветствуеся, если в тему)? Примечание. В Windows нельзя включить эмуляцию, так как во всех(даже хр) за это отвечает win87em.dll в системном каталоге. С какого компа на компах(с русским у меня туго, так как его у нас сейчас нету) всегда ставили сопроцессор? Объясни, как ты видишь ответы на эти(все) вопросы, если не трудно... ---------------------------------------------------------------------- И думал А.Гофман. И вначале отписался он Д.Хману про Сопроцесор, но не вошел ответ этот в Анналы, ибо не рулит он. И пошел еще думать А.Гофман. И не було в книгах ничего об этом. И пришлось своей башкой думать. И придумал он. И бысть ответъ Д.Хману, и вот какой: ----------------------------------------------------------------------- По первому вопросу. I. Теория Рассмотрим какой-нибудь тип с плавающей запятой, например real. В паскалевой справке сказано, что длина его 6 байт. Из них 5 отве- дено под мантиссу и 1 под порядок. Причем по одному биту в разде- ле мантиссы и порядка отведено для указания знака. Получается 39 бит выражает мантиссу (5*8-1) и 7 бит порядок. Ага. Какой из этого следует диапазон чисел? Поскольку нулю соот- ветствует значение знакового бита такое же, как и для положи- тельных чисел, то имеем 127 положительных (и ноль) и 128 отрица- тельных значений порядка. (2^7=128) Наименьшее отрицательное зна- чение -128; если говорить о самом маленьком числе, то оно должно иметь наименьший порядок и 1 в разделе мантиссы. Это 1*2^(-128)=2.93873587705571...*10^-39. Многоточие - это потому что число получается длинное; в типе real наименьшее число су- ществует строго, ведь число разрядов мантиссы конечно, но об этом далее. Наибольшее число должно иметь порядок 128 (двоичный), и, по идее, мантиссу вида 1,1111111111, то есть единички во всех 39 битах. Но вот почему-то в Турбопаскале принято, что мантисса числа с поряд- ком 128 может принимать лишь значение 1,0000000000. Тогда наибольшее число получается 1*2^127=1.70141183460469...*10^38. Ага. Теперь о мантиссе. Всем хороша двоичная система счисления, да только с десятичной она совмещается фигово. (проклятый бог, нет чтобы ему сотворить людей с 4 пальцами на руках, чтоб считали в восьмеричной систе- ме!!!). Фиговость заключается в том, что в какую степень 2-ку не возводи, кратного 10 числа не получишь, иначе говоря уравнение типо 2^(Ax)=10^(Bx) где A,B,x целые, решений вроде не имеет. Из этого и вытекает выражающаяся двумя смежными числами "точ- ность", как ты сказал. Это число значащих десятичных цифр, экви- валентных заданной разрядности мантиссы, на самом деле. 39-ю битами мантиссы можно записать 2^39=549755813888 чисел. Это 12-значное число, и вроде бы можно написать, что точность состав- ляет 12 разрядов, но стоп! Любое число, мантисса которого имеет 12 значащих цифр и значение меньше 5.49755813888eXX, спокойно за- пишется в 39 бит. Но вот число с величиной мантиссы больше этого, например 7,43760208422eXX, так уже не запишешь, т.к. 39 бит мало для записи такой мантиссы. Паскалю придется обрезать 12-ю послед- нюю циферку, чтобы мантисса стала меньше 549755813888. И значащих цифр станет 11. Тогда получается, что число десятичных знаков: 12 для мантиссы от 0 до 5.49755813888 11 для мантиссы от 5.497558139 до 9.9999999999. Такой же результат (11-12) можно получить из уравнения 2^39=10^x x=39lg2=11,7401... В свете этого наименьшие и наибольшие числа будут вот какие min=(+-)2,93873587706e-39 (12-й знак округлен) max=(+-)1,70141183461e+38 (аналогично). Составитель паскалевской справки просто забыл про отрицательные числа, они отлично кушаются компилятором. 2.Практика Для проверки этих гипотез я написал простенькую программку, кото- рая вводила число в real формате с клавиатуры и выводила его на экран. Так можно было проверить, правильно ли рассчитан числовой диапазон. Однако тут поджидал неприятный сюрприз, оказывается по умолчанию Паскаль показывает 11 разрядов мантиссы всегда. Однако когда я вводил 12 разрядное наименьшее число (cм. выше), он его скушивал, хоть и округлял последние 06 до 10, а когда вводилось чуть-чуть меньшее число, например кончащюееся на 05, как вместо числа появлялись нули. Так же было и с наибольшим числом, т.е. все правильно. А вот с 11 и 12 разрядами точности касяк. Методика проверки была вот какая: вводилось число с 12 разрядной мантиссой; потом от него отнималось число с тем же порядком, но только 2 первыми цифрами мантиссы и разность выводилась на экран. Например: _1,23456789012е24 1,20000000000е24 ----------------- 3,456789012е22 Расчет был на то, что если первая цифра мантиссы будет, например, шестерка, число выйдет за пределы 12разрядной точности и в раз- ности будет только 9 цифр, а не 10, как в предыдущем примере. Чтобы избавиться от касяка паскаля, выводящего 11 цифр мантиссы, в одном из опытов использовался форматированный вывод, формата :12:2 и числа вида 987654321098, т.е. без явного указания мантис- сы. Однако точность всегда составляла 12 разрядов, а по умолчанию по- казывались только 11; я подумал, что в паскале криво написан ал- горитм подобных вычислений. Тогда я включил 87-й. Но он аппаратно не рассчитан на тип такой длины и все вычисляет гораздо точнее, то есть в любом случае точность составляет более 12 разрядов, хо- тя: для чисел вида 8.xxxxxxxxxxx, 9.xxxxxxxxxxx вышеописанный эффект все же играет роль и в 12 разряде появляется мусор. То есть точ- ность 11 разрядов тоже иногда имеет место. Такие пироги. Продолжение следует.