从较大的数字类型转换为较小的数字类型时,潜在的陷阱是什么?

时间:2019-03-26 09:35:39

标签: c++ casting type-conversion

假定我正在使用返回foo的函数double,但是我正在程序中使用float(例如,许多计算机图形应用程序中的惯例)。 我不必为foo改写float,因为我不在很多地方使用,而且空间(以及可能还有速度)的开销不足以证明这样做的合理性。将foo设为可处理多种类型的函数模板也不是一种选择,因为该函数来自库。

我有多种选择来应对这种情况:

1)按原样使用该功能

float f = foo();

这会给编译器警告“可能丢失数据”,我想消除它,因为我确定在这种特殊情况下精度损失不是问题。

2)显式转换为float:

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

消除了警告,并向读者表明我正在转换为浮动在此处,但是使迅速掌握发生的情况变得更加困难,尤其是当行变长或需要强制转换多个参数时。

3)编写一个包装,将转换隐藏为浮动

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

没有警告,比(2)更易于阅读,但可能导致许多功能/ lambda并没有真正添加新功能。

我想知道:

  1. 是否有更多方法可以处理这种情况?
  2. 在三种方法之一中我是否缺少陷阱?

请注意,当我确定函数的结果适合我使用的较小类型时,整数类型可能会出现相同的问题。

1 个答案:

答案 0 :(得分:2)

您问:

Are there more ways to deal with this situation?

是的,例如,处理溢出问题-具有名为Numeric Conversion的库,该库可以公开并帮助处理这种情况。 (尤其是 numeric_cast

Am I missing pitfalls in one of the three approaches?

溢出。另外,在代码中留下这种已知的警告通常也是不可接受的。


  

概述

     

Boost数字转换库是用于   描述和执行不同数值之间的转换   类型。

     

该库为以下子集提供了一种特殊的替代方法   std :: numeric_limits <>,bounds <> traits类,它提供了一个   获取a范围的边界值的一致方法   数字类型。

     

它还包括一组特征类,它们描述了   从源到目标的转换的编译时属性   数字类型。算术和用户定义的数值类型都可以是   使用。

     

基于政策的转换器对象,该对象使用conversion_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.