简体   繁体   English

可以容纳两个size_t乘积的类型

[英]Type that can hold the product of two size_t

I have two size_t integers and need to take their product. 我有两个size_t整数,需要取它们的乘积。 In what type should I store the result? 我应该以哪种类型存储结果?

#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;
}

It looks like gcc defines size_t as an unsigned long long so I am not guaranteed I will be able to store the product... any alternatives? 看来gcc将size_t定义为unsigned long long所以我不能保证我将能够存储产品...还有其他选择吗?

Edit: 编辑:

The point here is that I am developing a library that needs to handle vectors of an arbitrary size, compute some statistic on it 这里的重点是我正在开发一个库,该库需要处理任意大小的向量,并对其进行一些统计

double stat = computeStatisticOnVectors(a, b);

and then compute the following: 然后计算以下内容:

double result = stat / prod

Have you considered not restricting yourself to a primitive type? 您是否考虑过不将自己限制为原始类型? If it's important to your application that such huge size_type values are handled, why not create a custom type which holds both original values? 如果处理这样巨大的size_type值对您的应用程序很重要,为什么不创建一个包含两个原始值的自定义类型呢?

It really depends on what you are trying to achieve with your code. 这实际上取决于您要使用代码实现的目标。

If you are later on going to use the value as a size_t (in other words, for sizing a vector, allocating memory, or some such), then you probably should do some checks that it's not overflowing, but store the value as a size_t . 如果以后要使用该值作为size_t (换句话说,用于确定向量的大小,分配内存等),则可能应该做一些检查,以确保它没有溢出,但将值存储为size_t You won't be able to use a bigger type anyway, if the purpose is to create a new object based on the size. 如果目的是基于大小创建新对象,则无论如何您将无法使用更大的类型。

If you are doing something like "calculating the number of possible combinations from these X vectors", then using a floating point type will probably be "good enough". 如果您正在执行“从这些X向量计算可能的组合数量”之类的操作,则使用浮点类型可能会“足够好”。

Up until 128 bits, and assuming you don't need much portability, you may just use built-in types such as uint128_t (supported at least by gcc and clang on x86_64 platforms). 直到128位,并且假设您不需要太多可移植性,您可以只使用内置类型,例如uint128_t (x86_64平台至少受gcc和clang支持)。

If you wish for more portability than this, then 128-bits integers are not standard, so you will need to: 如果您希望获得比此更高的可移植性,那么128位整数不是标准的,因此您需要:

  1. Define your own, a pair of 64-bits integer with overload operators would work 定义自己的一对带有重载运算符的64位整数将起作用
  2. Use an existing library, such as GMP (LGPL though, but much more generic) 使用现有的库,例如GMP(虽然是LGPL,但通用得多)
  3. From Marc Glisse: Boost.Multiprecision (without the license issue) 摘自Marc Glisse: Boost.Multiprecision(无许可证问题)

Of course, if you could simply eliminate this requirement it would be easier; 当然,如果您可以简单地消除此要求,它将更容易。 this product you are computing does not seem to mean much in itself, so just doing stat / na / nb might well be enough. 您正在计算的该产品本身并没有多大意义,因此仅执行stat / na / nb可能就足够了。

In your example you're multiplying 100000 and 100000 (rather untypically large values for sizes), where apparently you would want to obtain 10^10 exactly as a result. 在您的示例中,您将乘以100000和100000(大小的值通常不是很大),显然,您希望得到的结果恰好是10 ^ 10。

As a rough calculation based on 2^10 ~= 10^3, divide the 10's exponent by 3 and multiply by 10 to get the number of bits. 作为基于2 ^ 10〜= 10 ^ 3的粗略计算,将10的指数除以3并乘以10得到位数。 Now 10*10/3 is roughly 33, which means you need more than 32 bits, which means 64 bits. 现在10 * 10/3大约是33,这意味着您需要32位以上,也就是64位。 Thus, use a 64-bit type. 因此,请使用64位类型。

In addition to being 64-bit the type should be signed, because it's a good idea to use signed types for numbers (otherwise, due to implicit conversions you risk inadvertently using modular arithmetic, with hard to track down bugs). 除了使用64位之外,还应该对类型进行签名,因为对数字使用带符号的类型是个好主意(否则,由于隐式转换,您可能会无意中使用模块化算术,并且难以跟踪错误)。 So, the built-in type that you're looking for is – signed 64-bit integer – oh, that's long long . 因此,您要查找的内置类型是-带符号的64位整数-哦,那是long long

Or you can use one of the type aliases from <stdint.h> . 或者,您可以使用<stdint.h>中的类型别名之一。

That said, why on Earth are you multiplying large sizes, and why do you need the result as an exact integer? 就是说,为什么在地球上要乘以大尺寸,为什么需要将结果作为一个精确的整数?

Your statistics will be computed on vectors, which size will not exceed size_t capacity. 您的统计信息将根据向量进行计算,向量的大小不得超过size_t的容量。 I think it's enough to detect overflow in your case. 我认为足以检测到您的情况下的溢出。 I can think of a double conversion of each size, then compare the two products (size_t based product vs double product) 我可以想到每种尺寸的两次转换,然后比较两种产品(基于size_t的产品与双倍产品)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM