C++ 可容纳两种尺寸的产品的类型

C++ 可容纳两种尺寸的产品的类型,c++,integer-overflow,C++,Integer Overflow,我有两个size\u t整数,需要取它们的乘积。我应该以什么类型存储结果 #include <limits> #include <vector> #include <iostream> int main() { typedef std::size_t size_t; typedef unsigned long long product_t; std::vector<double> a(100000); std::

我有两个
size\u t
整数,需要取它们的乘积。我应该以什么类型存储结果

#include <limits>
#include <vector>
#include <iostream>

int main() {
    typedef std::size_t size_t;
    typedef unsigned long long product_t;

    std::vector<double> a(100000);
    std::vector<double> b(100000);

    size_t na {a.size()};
    size_t nb {b.size()};

    product_t prod = na * nb;

    std::cout << prod << std::endl;
}
然后计算以下各项:

double result = stat / prod

您是否考虑过不将自己限制为原始类型?如果处理如此大的类型值对您的应用程序很重要,为什么不创建一个包含两个原始值的自定义类型?

您是否考虑过不将自己限制为基本类型?如果处理如此大的大小类型值对您的应用程序很重要,为什么不创建一个同时保存原始值的自定义类型呢?

在您的示例中,您将100000和100000相乘(大小的值非常不典型地大),显然您希望得到10^10

作为基于2^10~=10^3的粗略计算,将10的指数除以3,再乘以10得到位数。现在10*10/3大约是33,这意味着需要超过32位,也就是64位。因此,请使用64位类型

除了64位之外,还应该对类型进行签名,因为对数字使用有符号类型是一个好主意(否则,由于隐式转换,您可能会无意中使用模块化算术,难以跟踪错误)。因此,您要查找的内置类型是–有符号64位整数–哦,这是
long

或者您可以使用
中的一个类型别名


也就是说,你到底为什么要将大尺寸相乘,为什么你需要一个精确的整数?

在你的例子中,你要将100000和100000相乘(尺寸的值非常不典型地大),显然你想要得到10^10的精确结果

作为基于2^10~=10^3的粗略计算,将10的指数除以3,再乘以10得到位数。现在10*10/3大约是33,这意味着需要超过32位,也就是64位。因此,请使用64位类型

除了64位之外,还应该对类型进行签名,因为对数字使用有符号类型是一个好主意(否则,由于隐式转换,您可能会无意中使用模块化算术,难以跟踪错误)。因此,您要查找的内置类型是–有符号64位整数–哦,这是
long

或者您可以使用
中的一个类型别名


也就是说,你到底为什么要乘以大的数值,为什么你需要一个精确的整数?

这实际上取决于你试图用你的代码实现什么

如果以后要将该值用作
size\u t
(换句话说,用于调整向量大小、分配内存等),则可能应该进行一些检查,确保它没有溢出,但将该值存储为
size\u t
。如果目的是基于大小创建新对象,则无论如何都不能使用更大的类型


如果您正在做类似“从这些X向量计算可能的组合数”的事情,那么使用浮点类型可能“足够好”

这实际上取决于您试图用代码实现什么

如果以后要将该值用作
size\u t
(换句话说,用于调整向量大小、分配内存等),则可能应该进行一些检查,确保它没有溢出,但将该值存储为
size\u t
。如果目的是基于大小创建新对象,则无论如何都不能使用更大的类型


如果您正在做类似“从这些X向量计算可能的组合数”的事情,那么使用浮点类型可能“足够好”

您的统计数据将在向量上计算,向量大小不会超过容量大小。 我认为在你的情况下检测溢出就足够了。
我可以考虑对每种尺寸进行双转换,然后比较两种产品(基于尺寸的产品与双产品)

您的统计数据将根据向量计算,向量的大小不会超过尺寸容量。 我认为在你的情况下检测溢出就足够了。
我可以考虑对每个大小进行双转换,然后比较这两种产品(基于大小的产品与双产品)

直到128位,并且假设您不需要太多的可移植性,您可以只使用内置类型,例如
uint128\u t
(至少在x86\u 64平台上由gcc和clang支持)

如果您希望具有更多的可移植性,则128位整数不是标准整数,因此您需要:

  • 定义您自己的,一对64位整数和重载运算符就可以了
  • 使用现有的库,如GMP(虽然是LGPL,但更通用)
  • 来自Marc Glisse:Boost.Multiprecision(无许可证问题)

  • 当然,如果你能简单地消除这个要求,它会更容易;您正在计算的这个产品本身似乎意义不大,所以只需执行
    stat/na/nb
    就足够了。

    直到128位,并且假设您不需要太多的可移植性,您可以只使用内置类型,例如
    uint128\u t
    (至少在x86\u 64平台上由gcc和clang支持)

    如果您希望具有更多的可移植性,则128位整数不是标准整数,因此您需要:

  • 定义您自己的,一对64位整数和重载运算符就可以了
  • 使用现有的库,如GMP(虽然是LGPL,但更通用)
  • 来自Marc Glisse:Boost.Multiprecision(无许可证问题)

  • 当然,如果你能简单地消除这个要求,它会更容易;您正在计算的这个产品本身似乎没有什么意义,所以只需执行
    stat/na/nb
    就足够了。

    我在Windows标题中看到的是一个名为的结构,它被设计用于容纳非常大的数字。那可能会帮你的忙
    double result = stat / prod