Характеристики на реални числа в Delphi - всичко за ИТ и програмиране

Написано на 08 януари 2009 г. Публикувано в Delphi

СЪДЪРЖАНИЕ

„Дефектен“ Разширен

Позволете ми да ви напомня, че казах малко по-горе, че копроцесорът винаги изпълнява всички операции в разширен формат, като същевременно уточнявам, че има изключение, към което ще се върна малко по-късно. Ако сте прочели всичко, което беше посочено по-горе, сега имате достатъчно знания, за да разберете какво е това изключение.

Копроцесорът има специален двубайтов регистър, наречен контролна дума. Задаването на отделни битове на този регистър диктува едно или друго поведение на копроцесора. На първо място, това се дължи на вида изключения, които копроцесорът може да създаде. Други битове от този регистър са отговорни за това как ще бъдат закръглени числата, как копроцесорът разбира безкрайността - всичко това може да се намери в документацията на Intel, ако е необходимо. Ще ни интересуват само два бита от тази дума - осмият и деветият. Те определят как ще се обработват числата вътре в копроцесора.

Ако осмият бит съдържа единица (това е по подразбиране), тогава десет байта от вътрешните регистри на копроцесора ще бъдат използвани изцяло и ще получим "пълен" Extended. Ако този бит е нула, тогава всичко се определя от стойността на бит 9. Ако е равно на единица, тогава се използват само 53 бита от мантисата (останалите винаги са нула). Ако този бит е равен на нула - само 24 бита от мантисата. Това увеличава скоростта на изчисленията, но намалява точността. С други думи, прецизността на копроцесора може да бъде намалена до двойна или дори единична. Но това се отнася само за мантисата, експонентата така или иначе ще съдържа 15 бита, така че обхватът на разширения тип се запазва във всеки случай.

За да работите с контролната дума на копроцесора всистемният модул описва променливата Default8087CW:Word и процедурата Set8087CW(CW:Word). Когато програмата стартира, променливата Default8087CW се задава на контролната дума, зададена от системата при стартиране на програмата. Функцията Set8087CW записва нова стойност в контролната дума. В същото време тази нова стойност се записва в променливата Default8087CW.

Това поведение на тази функция не винаги е удобно - понякога е необходимо да запазите старата стойност на променливата Default8087CW (но това е лесно да се направи чрез въвеждане на допълнителна променлива). От друга страна, ако стойността на контролната дума се промени без да се използва Set8087CW (и ще видим по-късно, че такива промени могат да възникнат против нашата воля), тогава с помощта на функцията Default8087CW просто няма начин да разберете текущата стойност на контролната дума. В Delphi 6 и по-нови се появи функцията Get8087CW, която ви позволява да разберете стойността на контролната дума, а не променливата Default8087CW. В по-ранните версии единственият начин да разберете значението на тази дума е използването на асемблер, особено след като в Delphi няма проблеми с вмъкванията на асемблер.

Стойността на контролната дума може да бъде зададена с командата FLDCW и прочетена с командата FNSTCW. И двете команди имат един аргумент - променлива от тип Word. За да зададете например 53-цифрената точност, без да променяте други битове на контролната дума, трябва да изпълните следната последователност от команди:

Съвременните копроцесори обработват числа с такава скорост, че при обикновени изчисления едва ли може да има нужда от ускорение поради прецизност - печалбата ще бъде незначителна. Тази функция се използва главно в случаите, когато изчисленията с плаваща запетая съставляват значителна част от програмата, а високата точност не еот фундаментално значение (например в двигатели за 3D игри). Не бива обаче да забравяте за тази функция на копроцесора, защото може да донесе една неприятна изненада, която ще бъде обсъдена малко по-късно.