Обнаружение потери точности при преобразовании из дважды для плавания

Я пишу часть кода, в котором я должен преобразовать из дважды для плавания значений. Я использую повышение:: numeric_cast, чтобы сделать это преобразование, которое предупредит меня любого переполнения/потери значимости. Однако я также интересуюсь знанием, если то преобразование привело к некоторой потере точности или нет.

Например,

    double source =  1988.1012;
    float dest = numeric_cast<float>(source);

Производит dest, который имеет значение 1988.1

Есть ли любой путь, доступный, в котором я могу обнаружить этот вид потери/округления точности

7
задан Yogesh Arora 13 July 2010 в 17:53
поделиться

4 ответа

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

11
ответ дан 6 December 2019 в 08:14
поделиться

Посмотрите в этих статьях одинарную точность и двойную точность с плавающей запятой. Во-первых, у чисел с плавающей запятой есть 8 бит для экспоненты против 11 для двойника. Таким образом, все, что больше 10 ^ 127 или меньше 10 ^ -126 по величине, будет переполнением, как вы упомянули. Для числа с плавающей запятой у вас есть 23 бита для фактических цифр числа и 52 бита для числа с двойной точностью. Итак, очевидно, что у вас намного больше цифр точности для double, чем для float.

Допустим, у вас есть число вроде: 1.1123. Это число не может быть на самом деле закодировано как 1.1123, потому что цифры в числе с плавающей запятой используются для фактического суммирования как дробей. Например, если ваши биты в мантиссе равны 11001, то значение будет сформировано как 1 (неявно) + 1 * 1/2 + 1 * 1/4 + 0 * 1/8 + 0 * 1/16 + 1 * 1/32 + 0 * (64 + 128 + ...). Таким образом, точное значение не может быть закодировано, если вы не можете сложить эти дроби таким образом, чтобы получить точное число. Это редко. Следовательно, почти всегда будет потеря точности.

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

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

Но, хорошая новость, это обычно стандартное IEEE число с плавающей точкой. :-)

1
ответ дан 6 December 2019 в 08:14
поделиться
float dest = numeric_cast<float>(source);
double residual = source - numeric_cast<double>(dest);

Следовательно, residual содержит искомый "убыток".

9
ответ дан 6 December 2019 в 08:14
поделиться
Другие вопросы по тегам:

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