Каковы потенциальные подводные камни при приведении числовых типов к большим или меньшим? - PullRequest
2 голосов
/ 26 марта 2019

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

У меня есть несколько вариантов решения этой ситуации:

1) Используйте функцию как есть:

float f = foo();

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

2) Явное приведение к плаванию:

float f = static_cast<float>(foo());

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

3) Напишите обертку, которая скрывает преобразование в число с плавающей точкой

float foo_float() { return static_cast<float>foo(); }
float f = foo_float();

Нет предупреждений и легче для чтения, чем (2), но потенциально приводит ко многим функциям / лямбдам, которые на самом деле не добавляют новых функций.

Хотелось бы знать:

  1. Есть ли еще способы справиться с этой ситуацией?
  2. Мне не хватает подводных камней в одном из трех подходов?

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

1 Ответ

2 голосов
/ 26 марта 2019

Вы спросили:

Are there more ways to deal with this situation?

Да, например, при работе с переполнением - имеет библиотеку под названием Числовое преобразование , которая выявляет и помогает справиться с ситуацией. ( в частности numeric_cast)

Am I missing pitfalls in one of the three approaches?

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


Обзор

Библиотека Boost Numeric Conversion - это набор инструментов для описать и выполнить преобразования между значениями различных числовых типы.

Библиотека включает специальную альтернативу для подмножества std :: numeric_limits <>, класс черт bounds <>, который обеспечивает последовательный способ получения граничных значений для диапазона числовой тип.

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

Объект конвертера на основе политик, который использует для выбора convert_traits оптимизированная реализация поставляется. Такая реализация использует код проверки оптимального диапазона, подходящий для источника / цели комбинация.

The converter's out-of-range behavior can be customized via an OverflowHandler policy.
For floating-point to integral conversions, the rounding mode can be selected via the Float2IntRounder policy.
A custom low-level conversion routine (for UDTs for instance) can be passed via a RawConverter policy.
The optimized automatic range-checking logic can be overridden via a UserRangeChecker policy.
...