C++ 整数类型宽度是给定类型宽度的两倍

C++ integer type twice the width of a given type

提问人:Bernard 提问时间:8/9/2016 最后编辑:maskBernard 更新时间:8/10/2016 访问量:2572

问:

在此示例中,是整数类型的别名,其大小至少是整数类型的两倍:coord_squared_tcoord_t

typedef int_least32_t coord_t;

coord_squared_t CalculateSquaredHypothenuse(coord_t x, coord_t y){
    coord_squared_t _x=x;
    coord_squared_t _y=y;
    return _x*_x+_y*_y;
}

什么可以用来表示?标准库中是否有任何内容允许我执行诸如获取正确宽度之类的操作,而不是显式选择类型?coord_squared_tcoord_tdouble_width<coord_t>::type

C++11 或 C++14 都可以。

C++ C++11 标准

评论

6赞 NathanOliver 8/9/2016
为什么不使用 fixed 和 这样的类型呢?int32_tint64_t
2赞 davidhigh 8/9/2016
您可以显式映射固定宽度的整数...没什么好看的,我承认
0赞 Bernard 8/9/2016
我可以,但根据参考,和朋友是可选的,只有保证在场。为四种整数类型编写条件是一种解决方案,但我希望能有更整洁的东西。int8_tint16_tint_leastN_t
0赞 Humam Helfawi 8/9/2016
超出范围:你确定double_width就足够了吗?
0赞 Bernard 8/9/2016
double_width就足够了,除了.除非 coord_t 是无符号整数类型。-2^31

答:

25赞 TartanLlama 8/9/2016 #1

你可以使用 boost::int_t:

using coord_squared_t = boost::int_t<sizeof(coord_t)*CHAR_BIT*2>::least;

评论

0赞 Bernard 8/9/2016
看起来像我想要的,但它是提升......如果没有其他答案,我会将其标记为已接受。
5赞 lisyarus 8/9/2016
@Bernard boost有什么问题?它甚至只是其中的标题部分。
0赞 Bernard 8/9/2016
提升没什么问题;我还没有编写足够的C++来需要使用boost。我想我会在我的代码中使用它。
3赞 lisyarus 8/9/2016
@Bernard Boost 是我们都需要的标准库中缺失部分的高质量提供者。我想你会喜欢 Boost :)
6赞 RiaD 8/10/2016
您可以考虑使用 8->CHAR_BIT
13赞 Barry 8/9/2016 #2

如果你不想使用 Boost,你可以通过一些专业化手动实现它:

template <class > struct next_size;
template <class T> using next_size_t = typename next_size<T>::type;
template <class T> struct tag { using type = T; };

template <> struct next_size<int_least8_t>  : tag<int_least16_t> { };
template <> struct next_size<int_least16_t> : tag<int_least32_t> { };
template <> struct next_size<int_least32_t> : tag<int_least64_t> { };
template <> struct next_size<int_least64_t> : tag<???> { };

// + others if you want the other int types

然后:

using coord_squared_t = next_size_t<coord_t>;

或者,您可以根据位数进行专业化:

template <size_t N> struct by_size : by_size<N+1> { };
template <size_t N> using by_size_t = typename by_size<N>::type;
template <class T> struct tag { using type = T; };

template <> struct by_size<8>  : tag<int_least8_t> { };
template <> struct by_size<16> : tag<int_least16_t> { };
template <> struct by_size<32> : tag<int_least32_t> { };
template <> struct by_size<64> : tag<int_least64_t> { };

这样,类似的东西是由于继承。然后这变得就像 Boost 答案一样:by_size<45>::typeint_least64_t

using coord_squared_t = by_size_t<2 * CHAR_BIT * sizeof(coord_t)>;

评论

1赞 Steve Jessop 8/10/2016
这可能适用于提问者真正关心的任何地方,但他表达的担忧是可选的。因此,它是否至少是 的两倍也是可选的。它们可能都是相同的类型,甚至(假设都是 64 位),在这种情况下,宽度不是 的两倍。Ofc 它仍然足够大,可以包含将两个大小不超过 2^31 的值相乘的结果,所以如果你控制你输入的内容,那么你就没问题了。intN_tint_least64_tint_least32_tnext_size_t<int_least32_t>int_least32_tcoord_t
0赞 Barry 8/10/2016
@SteveJessop 要求不是那个。要求是能够容纳下一个更大的比特量。sizeof(next_size_t<X>) == 2 * sizeof(X)next_size_t<X>
1赞 JDługosz 8/10/2016
问题在于,模板无法判断 16 位类型实际上是因为调用方使用 16 位,还是当他只需要 8 位时,它是否是可用的最小大小。他计划使用的域的大小可能小于实际类型,但这是决策应该基于的。
0赞 Steve Jessop 8/10/2016
@Barry:好吧,提问者他们想要一个宽度至少是给定类型两倍的类型。 保证其宽度至少是 的两倍。它只是保证宽度至少是 的下限的两倍。提问者完全有可能对他们的要求是错误的,而你是对的,这已经足够了。我只是认为值得指出的是,您已经更改了要求。int_least64_tint_least32_tint_least32_t
1赞 Steve Jessop 8/10/2016
请注意,有一些保护措施:现在或不久的将来存在这种有趣的架构的最可能的实际原因是因为没有小于 64 位的整数类型,并且所有 , , 都是同一类型。在这种情况下,代码会通过错误让您知道您已经多次定义了相同的专业化,您可以针对该平台进行修复:-)least16_tleast32_tleast64_t