Как компьютер конвертирует между типами

Итак, общий вопрос, который вы видите на SO, — как преобразовать тип x в тип z, но я хочу знать, как компьютер делает это?

Например, как он извлекает int из строки?

Моя теория состоит в том, что строка является массивом char в своей основе, поэтому она собирается по индексу по индексу и сравнивает его с таблицей ascii. Если он попадает в диапазон значений, то его добавляют к целому числу. Это происходит на еще более низком уровне, чем это? Есть ли битмасинг? Как это произошло?

Отказ от ответственности: не для школы, просто любопытно.

1

Решение

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

Единственный другой действительно отличный базовый тип — это указатель, который обычно не преобразуется каким-либо значимым образом (даже NULL проверка на самом деле не преобразование, а специальная встроенная семантика для 0 дословный).

int плавать и наоборот

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

строка целочисленного типа

Преобразование из строки в целое число довольно простое, потому что никаких числовых ошибок не произойдет. Действительно, любая строка является просто последовательностью кодовых точек (которая может или не может быть представлена char или же wchar_t), и общий метод для работы с этим идет по принципу следующего:

unsigned result = 0;
for(size_t i = 0; i < str.size(); ++i) {
unsigned c = str[i] - static_cast<unsigned>('0');
if(c > '9') {
if(i) return result; // ok: integer over
else throw "no integer found";
}
if((MAX_SIZE_T - c) / 10 < result) throw "integer overflow";
result = result * 10 + c;
}

Если вы хотите рассмотреть такие вещи, как дополнительные базы (например, такие строки, как 0x123 как шестнадцатеричное представление) или отрицательные значения, это, безусловно, требует еще нескольких тестов, но основной алгоритм остается тем же.

int в строку

Как и ожидалось, это в основном работает в обратном порядке: реализация всегда будет брать остаток от деления на 10, а затем делить на 10. Поскольку это даст число в обратном порядке, можно либо напечатать в буфер с обратной стороны, либо сторнировать результат снова.

строка с типом с плавающей точкой

Разбор строк в double (или же float) значительно сложнее, поскольку предполагается, что преобразование происходит с максимально возможной точностью. Основная идея здесь состоит в том, чтобы прочитать число в виде цепочки цифр, помня только, где была точка и какова экспонента. Затем вы должны собрать мантиссу из этой информации (которая в основном представляет собой 53-разрядное целое число) и экспоненты и собрать фактическую битовую комбинацию для полученного числа. Затем он будет скопирован в целевое значение.

Хотя этот подход работает отлично, в буквальном смысле используются десятки различных подходов, каждый из которых отличается по производительности, правильности и надежности.

Актуальные реализации

Обратите внимание, что в реальных реализациях может потребоваться сделать еще одну важную (и ужасно уродливую) вещь — локаль. Например, в немецком языке «,» — это десятичная точка, а не разделитель тысяч, поэтому число «пи» примерно равно «3,1415926535».

Perl-строка для удвоения
Строка TCL, чтобы удвоить
Дэвид М. Гей AT&T Бумажная нить для удвоения, двойная для нити и исходный код
Повысить дух

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]