Вопрос

Насколько дорогостоящим является преобразование float к a double?Является ли это таким же тривиальным, как int Для long обращение?

Редактировать:Я предполагаю платформу, где значение float равно 4 байтам, а double - 8 байтам

Это было полезно?

Решение

Соображения о платформе

Это зависит от платформы, используемой для вычисления float.В x87 FPU преобразование бесплатное, поскольку содержимое регистра остается тем же - единственная цена, которую вы иногда можете заплатить, - это трафик памяти, но во многих случаях трафика даже нет, поскольку вы можете просто использовать значение без какого-либо преобразования.x87 на самом деле странный зверь в этом отношении - на нем трудно правильно различить значения с плавающей точкой и удвоения, поскольку используемые инструкции и регистры одинаковы, отличаются инструкции загрузки / сохранения, а сама точность вычислений контролируется с помощью битов состояния.Использование смешанных вычислений с плавающей запятой / double может привести к неожиданным результатам (и из-за этого существуют параметры командной строки компилятора для управления точным поведением и стратегиями оптимизации).

Когда вы используете SSE (а иногда Visual Studio использует SSE по умолчанию), это может отличаться, так как вам может потребоваться перенести значение в регистры FPU или сделать что-то явное для выполнения преобразования.

Производительность при экономии памяти

В качестве резюме и ответа на ваш комментарий в другом месте:если вы хотите сохранить результаты плавающих вычислений в хранилище объемом 32 Б, результат будет таким же или быстрее, потому что:

  • Если вы сделаете это на x87, преобразование будет бесплатным - единственное отличие будет заключаться в том, что вместо fstp qword[] будет использоваться fstp dword.
  • Если вы сделаете это с включенным SSE, вы можете даже увидеть некоторый прирост производительности, поскольку некоторые вычисления с плавающей запятой могут быть выполнены с помощью SSE, если точность вычислений равна только float вместо double по умолчанию.
  • Во всех случаях объем памяти меньше

Другие советы

Преобразования с плавающей запятой в double выполняются бесплатно на некоторых платформах (PPC, x86, если ваш компилятор / среда выполнения использует режим оценки "к черту тот тип, который вы мне сказали использовать, я все равно собираюсь оценить все в режиме long double, ня-ня-ня").

В среде x86, где вычисление с плавающей запятой фактически выполняется в указанном типе с использованием регистров SSE, преобразования между float и double примерно такие же дорогие, как сложение или умножение с плавающей запятой (т. Е. вряд ли будут учитываться с точки зрения производительности, если вы не выполняете очень много из них).

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

Это относится к используемой вами реализации C ++. В C ++ типом с плавающей точкой по умолчанию является double . Компилятор должен выдать предупреждение для следующего кода:

float a = 3.45;

потому что двойному значению 3.45 присваивается значение с плавающей точкой. Если вам нужно использовать float, добавьте суффикс к значению f :

float a = 3.45f;

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

См. также раздел 4.5 в языке программирования C ++ .

Я не могу себе представить, что это будет намного сложнее. Большая разница между преобразованием int в long и преобразованием float в double заключается в том, что типы int имеют два компонента (знак и значение), а числа с плавающей запятой имеют три компонента (знак, мантисса и экспонента).

  

IEEE 754 с одинарной точностью кодируется   в 32 битах, используя 1 бит для знака, 8   биты для показателя степени и 23 бита для   Значение и. Тем не менее, он использует   скрытый бит, поэтому значение равно 24   биты (р = 24), хотя это   кодируется с использованием только 23 битов.

- Дэвид Голдберг, Что должен знать каждый учёный-компьютерщик с плавающей точкой Арифметика

Таким образом, преобразование между float и double будет сохранять один и тот же знаковый бит, установите последние 23/24 бита мантиссы float в мантиссу двойного и установите последние 8 бит экспоненты float в показателе double.

Такое поведение может быть гарантировано даже IEEE 754 ... у меня нет проверил, так что я не уверен.

вероятно немного медленнее, чем преобразование int в long, так как требуемая память больше и манипулирование более сложным. Хорошая справка о проблем с выравниванием памяти

Может быть, это поможет:

#include <stdlib.h>
#include <stdio.h>
#include <conio.h>

double _ftod(float fValue)
{
  char czDummy[30];
  printf(czDummy,"%9.5f",fValue);
  double dValue = strtod(czDummy,NULL);
  return dValue;
}


int main(int argc, char* argv[])
{
  float fValue(250.84f);
  double dValue = _ftod(fValue);//good conversion
  double dValue2 = fValue;//wrong conversion
  printf("%f\n",dValue);//250.840000
  printf("%f\n",dValue2);//250.839996
  getch();
  return 0;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top