Рубрики
Uncategorized

Примечания ко второму уроку парадигмы программирования Стэнфорда – Представление типов данных в памяти

Автор оригинала: David Wong.

Минимальная единица памяти-байты. Байт равен 8 битам. Каждый бит равен либо 0, либо 1, то есть представлен двоичным кодом.

Представление байта в памяти является:

Представление целых чисел без знака

Беззнаковая двоично – десятичная формула:

  • w : длина двоичного бита.
  • i : индекс двоичных битов, начинающийся справа налево, считая от 0.
  • w-1 : поскольку I отсчитывается от 0, последним индексом является W-1.
  • x(i) : Нет. i Бит, либо 0, либо 1.
  • 2^i 2. i Вторая степень.

Например: Двоичное число без знака 10010 Разверните в соответствии с формулой:

Если это число хранится в компьютере с одним байтом, память представляется в виде:

Меньше 8 цифр, заполните 0 слева.

Байт может быть представлен формально без символа 2^8 Разными числами. Число, которое может представлять максимальное число, состоит из 8 двоичных цифр, все из которых 1 равно 255, то есть найдите одну Общее соотношение равно 2. , Первый элемент равен 1. Из Геометрического ряда Топ-8 и. Формула двоичного суммирования битов (2^n) - 1 . Суммируйте следующее n-разрядное двоичное число , которое может представлять максимальное число (2^n) - 1 , способное представлять 2^n Существуют разные числа. Причина , по которой существует 2 ^ n разных чисел, заключается в том, что они могут представлять 0~(2^n) - 1 , начиная с 0, поэтому вам нужно +1 Длина.

Представление символа в памяти

Тип Char используется для хранения одного символа, который занимает 1 байт в памяти. Он использует 8 бит для представления 256 символов. Тип Char фактически хранит символы ASCII Кода в результате ASCII Код представляет собой целое число. Таким образом, символ-это 8-разрядное целое число в памяти.

Например, символы A Из ASCII Код равен 65, ^ 0 + 2 ^ 6, поэтому выражение в памяти является:

char ch = 'A';
printf("%d", ch); // output is 65

Короткая память

Short представляет собой короткий целочисленный тип, обычно занимающий 2 байта памяти.

Его диапазон значений составляет (-2)^15~(2^15)-1 Содержит 0. Максимум здесь (2^15)-1 , поскольку короткий имеет знаковые биты, вам нужно использовать самый старший бит (первый бит слева направо) для представления знака, 0 для положительного числа и 1 для отрицательного числа. Двоичное представление максимального значения равно 0111111111111111 (16 двоичных разрядов), десятичное число равно (2^15)-1 。 Причина в том, что (2^15)-1 Это также формула суммирования( (2^n)-1

Реализация сложения и вычитания

Двоичное сложение и вычитание совпадают с десятичной системой позиция Сложение, перенос, если больше 1. например 0111 +

Если вы хотите добавить 7 и – 7, чтобы результат был равен 0. Согласно старшему разряду двоичного кода, используемому в компьютере в качестве знакового бита, 0 представляет положительное число, 1 представляет отрицательное число. Так что 7-это 0000111 , – 7 выражается как 1000111 。 0000111 + 1000111 в соответствии с предыдущим правилом сложения двоичной системы, результатом является 1001110 , результат не тот 0, который мы хотим.

Как я могу сложить два двоичных числа, чтобы получить 0?

Чтобы получить 0, вам нужно использовать перенос, например 11111111 На основе 8 единиц добавьте 1, чтобы получить 100000000 (всего 9 цифр, первая слева-1, а последние 8 нулей). Если вы отбросите самый левый, вы получите 8 нулей, а конечный результат равен 0. Двоичное число всех 1 может быть получено путем инвертирования исходного кода по битам и добавления его к исходному коду. такие, как 0000111 Реверс по битам 1111000 Эти двое складываются вместе 11111111 。 Добавьте к нему 1, чтобы получить конечный результат 0. Весь процесс состоит из трех этапов. Мы объединяем последние два шага в один шаг, который заключается в объединении побитового отрицания и плюс 1. Фактически, мы добавляем 1 к обратному исходному коду. как 1111000 Плюс 1 получает 1111001 。 Последние два шага вместе называются дополнением исходного кода. Последнее 1111001 Это называется 0000111 Дополнение.

  • Дополнением положительного целого числа является само по себе.
  • Дополнение отрицательного целого числа состоит в том, чтобы по битам инвертировать двоичный код соответствующего положительного целого числа, то есть создать обратный код исходного кода, а затем добавить 1.

Например, положительное целое число 7 Двоичный код is 0000111 , его дополнением является он сам. Еще один пример -7 Соответствующий двоичный код с положительным целым числом является 0000111 , противоположностью которой является 1111000 (переверните исходный код по частям). Затем еще раз Плюс 1 Получаем 11110011111001 А именно -7 Дополнение. Еще раз, мы ставим 1111001 и 0000111 Согласно правилу двоичного сложения, сумма просто равна 0. Здесь следует отметить, что с левой стороны будет бит переполнения. Если бит переполнения удален, результат будет равен 0.

-Дополнение 1 равно 1, потому что оно становится 0, когда добавляется 1.

Компьютерная система использует код дополнения для выражения двоичного кода, одним из преимуществ которого является то, что сложение и вычитание могут обрабатываться равномерно.

Копирование в битовом режиме

Когда ставится символ Переменная типа, присвоенного короткий Когда переменная типа символ 8 бит короткий Первый байт справа налево.

Например:

Char ch = 'a'; // 'a' ASCII: 65 memory is 01000001
Short s = ch; // memory represents 00000000 | 01000001

Особая ситуация заключается в том, чтобы рассматривать короткое Из -1 Назначьте переменной int , мы не получим 00000000 | 00000000 | 11111111 | 11111111 Потому что в этом случае значение не -1 Сейчас же. Так что правильный путь-это Все 1 Скопируйте все в int . Например:

Short s = - 1; // memory is 11111111 | 11111111
Int i = s; // memory is represented as 11111111 | 11111111 | 11111111 | 11111111111

Напротив, если короткая Переменная типа назначена символу , Когда переменная типа короткая В нижнем октете (первый байт справа налево) символ Только один байт. Это автоматически удалит много байтов. Например:

Short s = 65; // memory represents 00000001 | 01000001
Char ch = s; // memory is 01000001

Представление чисел с плавающей запятой

Мы знаем, что формула преобразования двоичного кода без знака в десятичный является:

Там я Он начинается с 0, который является первым справа 2^0 Если мы начнем с отрицательного целого числа, то будет отрицательная целочисленная степень, а затем будет десятичная часть. Например, существует 16-разрядное двоичное число 000000011 | 11000000 Это также может быть выражено с помощью первых восьми цифр для представления целочисленной части и последних восьми цифр для представления десятичной части 000000011.11000000 。 Таким образом, последние восемь битов больше не являются целыми степенями, но каждый бит слева направо 2^(-1)~2^(-8) 。 Это число может быть выражено следующим образом:

Это один из методов представления чисел с плавающей запятой. Точность числа с плавающей запятой, представленного этим методом, будет недостаточной, а диапазон значений, представленный этим методом, относительно невелик, поэтому компьютер не использует этот метод для представления числа с плавающей запятой на практике.

Следующий метод представляет собой реальное представление чисел с плавающей запятой внутри компьютера.

Давайте сначала рассмотрим научный метод подсчета в десятичной системе. Если мы используем научный метод подсчета, чтобы выразить 123,45, это 1.2345 * 10^2 。 Где 1.2345-это Мантисса 10. база 2. индекс . Когда компьютер выражает числа с плавающей запятой, он также заимствует идею десятичного научного метода подсчета, но базовое число равно 2 Сейчас же.

например 1000.01 Это может быть выражено следующим образом 1.00001 * 2^3 Десятичная точка перемещается на несколько мест вправо.

используйте 32 место Из с плавающей точкой Например, первым является знаковый бит S , внимательно следите 8 место Цифры E Наконец 23 место Называется последней цифрой M

Формула расчета:

  • S: бит символа

Когда s равно 0, это положительное число, когда s равно 1, это отрицательное число.

  • М: мантисса

Его диапазон значений составляет 1≤M<2 , значение берется слева направо. Каждый бит представляет 2^-1~2^-23 Затем значение представляет собой сумму значений представления каждого бита, что согласуется с предыдущим представлением чисел с плавающей запятой, начиная с отрицательной целочисленной степени. Потому что целая часть мантиссы всегда 1 , так что это 1 Его можно опустить, чтобы добавить еще один бит для повышения точности.

  • E: индексная часть

127 вычитается, потому что смещение равно 127.

например 0 | 10000010 | 11110000000000000000000 Каждая часть является:

  • S: 0

Представляет целое число.

  • М: 11110000000000000000000

Здесь нам нужно добавить 1, потому что для повышения десятичной точности мы опускаем 1, поэтому нам нужно добавить его обратно. Так что вся мантисса должна быть 1.1111 (следующий 0 опущен) 2^0 + 2^-1 + 2^-2 + 2^-3 +.9375

  • E: 10000010

2^7 +

Формула переносится отдельно

Двоичная форма:

Десятичная форма:

Детальный процесс: 1 * 1.1111 * 2^(130-127) => 1 * 1.1111 * 2^3 => 1 * 1111.1 (несколько степеней, десятичная точка перемещается на несколько мест вправо) = > 1 * (2^3 + 2^2 + 2^1 + 2^0 + 2^-1) => 1 * (8 + 4 + 2 + 1 + 0.5) => 15.5

Числа с плавающей запятой и целые числа присваиваются друг другу

Когда мы присваиваем числа с плавающей запятой и целые числа друг другу, мы не будем напрямую копировать битовые биты, а пересчитаем битовые шаблоны в новом типе. Например:

Int i = 5; // memory means 00000000 | 00000000 | 00000000 | 00000101
//Recalculate the representation of 5 in float
Float f = I; // memory represents 0 | 00000000 | 00000000000000000000101
printf("%f", f) // output is 5.0

Немного более захватывающе!!!

// 2^30
Int i = 1073741824; // memory means 01000000 | 00000000 | 00000000 | 00000000
//The representation in float will not be recalculated here, but the bit bit will be copied directly. Use float to parse the memory of int.
Float f = * (float *) & I; // memory represents 0 | 10000000 | 00000000000000000000000

// 1 * 2^(128-127) * 1 = 2
printf("%f", f) // output is 2.0

Здесь нет пересчета 1073741824 В плавающей строке это выражается напрямую в Из Битовой копии прошлого . Использование аналитического метода с плавающей точкой в Память для разбора int