Материал: Программные преобразования числовой информации (96

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Program Prog1;

Type

rCardSingl = Record

Case Byte of

0:(n:cardinal);

1:(f:single);

end;

Procedure BinaryInt(w:cardinal); var

mask : cardinal; begin

mask := $80000000; While mask<>0 Do

begin

If w and mask =0 Then Write ('0') Else Write ('1');

mask := mask shr 1; end;

end;

var

x : Single;

g: rCardSingl; begin

Readln (x); g.f :=x;

BinaryInt(g.n);

Readln;

end.

В результате выполнения программы Prog1 на экран будет выведена следующая информация:

6.25

01000000110010000000000000000000 -6.25 11000000110010000000000000000000

0.25

00111110100000000000000000000000 -0.25 10111110100000000000000000000000

1.25

16

00111111101000000000000000000000 -1.25 10111111101000000000000000000000

В начале программного файла Prog1 находится объявление типа rCardSingl , в котором область из 4 байт можно рассматривать как формат типа cardinal или как формат single. По формату поля f вещественное число загружается в область типа, а по формату n применяются битовые конъюнкция и сдвиг.

Анализ битового представления числа в формате single требует пояснения. Начнем с мантиссы числа, например 6,25. Мантисса занимает биты 0 – 22 . В строке монитора это число имеет мантиссу, показанную на рис. 2.

 

22

 

21

 

20

 

19

18

17

16

15

14

13

12

11

 

 

1

 

0

 

0

 

1

 

0

 

0

 

0

 

0

 

0

 

0

 

0

 

0

 

 

10

9

8

 

 

7

 

6

 

5

 

4

 

3

 

2

 

1

 

0

 

 

 

0

 

0

 

0

 

 

0

 

0

 

0

 

0

 

0

 

0

 

0

 

0

 

 

 

 

 

 

 

 

Рис. 2. Мантисса числа 6,25 в переменной типа single

 

 

 

 

Следует обратить внимание на то, что нормализованное двоич-

ное представление числа 6,25

имеет вид

 

0,11001 1032 . Казалось

бы, на рис. 2 отсутствует старшая единица мантиссы. Но так как все нормализованные двоичные числа (за исключением нуля) обязательно содержат единицу в начале дробной части мантиссы, то можно не хранить эту единицу, тем самым увеличивая хранимую в памяти мантиссу на 1 бит. Так получаем небольшой выигрыш по точности производимых вычислений. Если число необходимо вывести на монитор, то эту «скрытую» единицу восстанавливают. Бит 31 содержит 0, если число положительное, 1 – если число отрицательное.

Теперь обратим внимание на порядок числа. В формате single он занимает биты 23 – 30. Порядок числа 6,25 показан на рис. 3.

30

29

28

27

26

25

24

23

1

0

0

0

0

0

0

1

Рис. 3. Порядок числа 6,25 в переменной типа single

17

Чтобы получить истинное число, бит 30 можно интерпретировать как бит направления сдвига мантиссы. Если значение в этом бите равно 1, то имеем положительный порядок, и мантиссу следует сдвинуть влево. Если – 0, то порядок отрицательный, и мантиссу необходимо сдвигать вправо. Порядок хранимой мантиссы определяется после добавления 1 к битам 23 – 29. Это порядок 2 для числа 6,25.

Возможна другая интерпретация значения бита 30. Если значение бита 30 прибавить к битам 23 – 29, то получим порядок хранимой мантиссы. Так, для целой части 6 порядок хранимой мантиссы равен двум.

В любом случае к полученному результату необходимо приписать «скрытую» 1 перед началом числа. Для числа 6,25 хранимая мантисса – 1001. Истинная мантисса – это 11001.

Отрицательные порядки нормализованных чисел в формате single хранятся в обратном коде. Например, при выполнении

программы Prog1 число 0,2510 = 0,12 1021 изображено на мони-

торе с нулевой мантиссой в битах 0 – 22. Это связано с тем, что старшая единица мантиссы скрыта. А поскольку в числе 0,25 находится только одна единица, то хранимая мантисса представляется как 0. Порядок числа 0,25 показан на рис. 4.

30

29

28

27

26

25

24

23

0

1

1

1

1

1

0

1

Рис. 4. Порядок числа 0,25 в переменной типа single

Биты 23 – 29 содержат обратный код числа 2. После инверсии бит 23 – 29 получаем число 0000010. Это ровно столько, сколь необходимо сделать одиночных сдвигов вправо, чтобы получить из «спрятанной» единицы число 0,012.

Особый интерес вызывает хранение чисел с единицей в целой части. По результатам программы видно, что хранимая мантисса числа 1,25 имеет вид, показанный на рис. 5.

Опять следует принять во внимание «спрятанную» единицу. Поэтому в мантиссе остается только «дробная часть» 012. Порядок числа 1,25 выглядит несколько своеобразно в «отрицательном» виде, хотя число 1,25 имеет явно положительный порядок (рис. 6).

18

22

21

20

 

19

18

 

17

 

 

16

 

15

14

 

13

 

12

0

 

 

1

 

 

 

0

 

 

0

0

 

0

 

 

 

0

 

 

 

0

0

 

0

 

 

0

 

 

 

11

 

10

 

9

8

7

 

6

 

5

4

3

2

 

1

 

0

 

 

 

0

 

 

0

 

 

0

 

0

 

0

 

0

 

0

 

0

 

0

 

0

 

0

 

0

 

 

 

Рис. 5. Мантисса числа 1,25 в переменной типа single

 

 

30

 

29

 

 

28

27

 

 

 

26

 

 

 

25

24

 

23

 

 

 

 

 

0

 

 

 

1

 

 

1

 

1

 

 

 

1

 

 

 

 

1

 

1

 

 

1

 

 

 

 

Рис. 6. Порядок числа 1,25 в переменной типа single

Инверсия бит 23 – 29 дает порядок 0 для хранимой мантиссы числа 1,25. При восстановлении истинного вида числа к хранимой мантиссе будет приписана единица слева, т. е. получаем

012 ~ 1,012 = 0,2510.

7. МОДЕЛИРОВАНИЕ ПРЕОБРАЗОВАНИЯ single - integer

В представляемой ниже программе Prog2 запрограммированы действия, которые рассматривались в разд. 6 для получения истинного кода целой части числа из порядка и хранимой мантиссы вещественного числа в формате single.

Чтобы понять, каким образом создается порядок целой части числа в формате single, напишем программу Prog2, в которой произвольное вещественное четырехбайтное число в формате single преобразуется в целое четырехбайтное число формата integer. Это равносильно определению целой части вещественного числа. Следует отметить, что возможности языков программирования позволяют решить задачу с помощью стандартных средств:

n := Trunc( 6.25 );

19

Однако за такой простотой одной инструкции скрывается выполнение действий, подобных функции FloatInt() из програм-

мы Prog2.

Program Prog2;

Type

rCardSingl = Record

Case Byte of

0:(n:cardinal);

1:(f:single);

end;

Procedure BinaryInt(s:string;w:integer;k:byte); var

mask : cardinal; begin

If k=32 Then mask := $80000000 Else If k=16 Then mask := $8000

Else If k=8 Then mask := $80 Else Exit;

Write (s); While mask<>0 Do

begin

If w and mask =0 Then Write ('0') Else Write ('1');

mask := mask shr 1; end;

Writeln;

end;

Function FloatInt (ff:single):integer; var

g: rCardSingl; t,z:integer; p:byte;

begin

g.f := ff;

If g.n=0 Then begin Result:=0; Exit;

end;

20

Источник: https://studfile.net/preview/16723858/