Целое число по сравнению с плавающим подразделением->, Кто ответственен за обеспечение результата?

Я программировал некоторое время в C++, но внезапно имел сомнение и требуемый для разъяснения с сообществом Stackoverflow.

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

Но кто ответственен за обеспечение этого результата? Действительно ли это - инструкция DIV или компилятор?

7
задан nsivakr 15 August 2010 в 16:05
поделиться

6 ответов

Компилятор решит во время компиляции, какая форма деления требуется, в зависимости от типов используемых переменных - в конце дня инструкция DIV (или FDIV) одной формы или другой будет участвовать.

3
ответ дан 6 December 2019 в 09:17
поделиться

Это зависит от того, есть ли в вашей архитектуре инструкцию DIV . Если в вашей архитектуре есть инструкции деления как с целыми числами, так и с плавающей запятой, компилятор выдаст правильную инструкцию для случая, указанного в коде. Стандарт языка определяет правила повышения типа и то, следует ли использовать целочисленное или плавающее деление в каждой возможной ситуации.

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

12
ответ дан 6 December 2019 в 09:17
поделиться

Инструкции аппаратного разделения почти никогда не включают преобразование между целым числом и плавающей запятой. Если вы вообще получаете инструкции деления (их иногда пропускают, потому что схема деления большая и сложная), они практически наверняка будут «делить int на int, производить int» и «делить float на float, производить float» . И обычно оба входа и выхода тоже имеют одинаковый размер.

Компилятор отвечает за построение любой операции, написанной в исходном коде, поверх этих примитивов. Например, в C, если вы разделите число с плавающей запятой на int, компилятор выдаст преобразование типа int в число с плавающей запятой, а затем разделит число с плавающей запятой.

(Дурацкие исключения действительно существуют. Я не знаю, но я бы не стал отказываться от VAX, чтобы иметь инструкции типа "разделить float на int".В Itanium действительно не было инструкции деления, но его «помощник деления» был только для чисел с плавающей запятой, вам приходилось имитировать целочисленное деление поверх деления с плавающей запятой!)

3
ответ дан 6 December 2019 в 09:17
поделиться

Ваш вопрос действительно не имеет смысла. Инструкция DIV ничего сама по себе не делает. Независимо от того, насколько громко вы на него кричите, даже если вы попытаетесь его подкупить, он не несет ответственности ни за что

Когда вы программируете на языке программирования [X], это единственная ответственность [ X], чтобы создать программу, которая выполняет то, что вы описали в исходном коде .

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

Но всегда зависит от компилятора. Ваша программа на C ++ не имеет никакого эффекта , если она не интерпретируется в соответствии со стандартом C ++. Если вы интерпретируете его как простой текстовый файл, он ничего не делает . Если ваш компилятор интерпретирует его как программу Java, он захлебнется и отклонит его.

И инструкция DIV ничего не знает о стандарте C ++. С другой стороны, компилятор C ++ написан с единственной целью - понять стандарт C ++ и преобразовать код в соответствии с ним.

Компилятор всегда несет ответственность .

1
ответ дан 6 December 2019 в 09:17
поделиться

Одно из наиболее важных правил в стандарте C ++ - это «как Правило if:

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

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

Он также может:

  1. Заменить операцию битовым сдвигом, если это необходимо и, вероятно, будет быстрее.
  2. Замените операцию литералом, если она вычислима во время компиляции, или присваиванием, если, например, при обработке x / y во время компиляции можно показать, что y всегда будет 1.
  3. Замените операцию выбросом исключения, если во время компиляции можно показать, что это всегда будет целочисленное деление на ноль.
1
ответ дан 6 December 2019 в 09:17
поделиться

Практически

Стандарт C99 определяет: "При делении целых чисел результатом оператора / является алгебраический коэффициент с любой дробной частью отбрасывается". И добавляет в сноске, что "это часто называют "усечением к нулю"."

История

Исторически за спецификацию языка отвечают.

Паскаль определяет свои операторы так, что использование / для деления всегда возвращает real (даже если вы используете его для деления двух целых чисел), а если вы хотите разделить целые числа и получить целочисленный результат, вы используете оператор div вместо него. (В Visual Basic есть аналогичное различие и используется оператор \ для целочисленного деления, которое возвращает целочисленный результат.)

В C было решено, что такое же различие должно быть сделано путем приведения одного из целочисленных операндов к float, если вы хотите получить результат с плавающей точкой. Во многих языках, производных от языка Си, стало принято рассматривать целочисленные типы в сравнении с типами с плавающей точкой так, как вы описали. Я подозреваю, что это соглашение могло зародиться в Фортране.

0
ответ дан 6 December 2019 в 09:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: