如何将 size_t 转换为 double 或 int C++
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22184403/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to cast the size_t to double or int C++
提问by user2701639
My question is that
我的问题是
I have a size_t data, but now I want to convert it to double or int.
我有一个 size_t 数据,但现在我想将其转换为 double 或 int。
If I do something like
如果我做类似的事情
size_t data = 99999999;
int convertdata = data;
the compiler will report warning. because it maybe overflow.
编译器会报告警告。因为它可能会溢出。
Do you have some method like the boost or some other method to do the convert?
您是否有一些方法,如 boost 或其他一些方法来进行转换?
回答by Keith Thompson
A cast, as Blaz Bratanic suggested:
size_t data = 99999999;
int convertdata = static_cast<int>(data);
is likely to silence the warning (though in principle a compiler can warn about anything it likes, even if there's a cast).
可能会使警告静音(尽管原则上编译器可以警告它喜欢的任何东西,即使有强制转换)。
But it doesn't solve the problem that the warning was telling you about, namely that a conversion from size_t
to int
really could overflow.
但这并没有解决警告告诉您的问题,即从size_t
到的转换int
确实可能溢出。
If at all possible, design your program so you don't needto convert a size_t
value to int
. Just store it in a size_t
variable (as you've already done) and use that.
如果可能,请设计您的程序,以便您无需将size_t
值转换为int
. 只需将它存储在一个size_t
变量中(正如您已经完成的那样)并使用它。
Converting to double
will not cause an overflow, but it could result in a loss of precision for a very large size_t
value. Again, it doesn't make a lot of sense to convert a size_t
to a double
; you're still better off keeping the value in a size_t
variable.
转换为double
不会导致溢出,但对于非常大的size_t
值可能会导致精度损失。同样,将 a 转换size_t
为 a没有多大意义double
;您最好将值保留在size_t
变量中。
(R Sahu's answerhas some suggestions if you can't avoid the cast, such as throwing an exception on overflow.)
(如果您无法避免强制转换,R Sahu 的回答有一些建议,例如在溢出时抛出异常。)
回答by Blaz Bratanic
Static cast:
静态投射:
static_cast<int>(data);
回答by R Sahu
If your code is prepared to deal with overflow errors, you can throw an exception if data
is too large.
如果你的代码准备处理溢出错误,你可以抛出一个异常如果data
太大。
size_t data = 99999999;
if ( data > INT_MAX )
{
throw std::overflow_error("data is larger than INT_MAX);
}
int convertData = static_cast<int>(data);
回答by Steve Jessop
You can use Boost numeric_cast
.
您可以使用 Boost numeric_cast
。
This throws an exception if the source value is out of range of the destination type, but it doesn't detect loss of precision when converting to double
.
如果源值超出目标类型的范围,这将引发异常,但在转换为double
.
Whatever function you use, though, you should decide what you want to happen in the case where the value in the size_t
is greater than INT_MAX
. If you want to detect it use numeric_cast
or write your own code to check. If you somehow know that it cannot possibly happen then you could use static_cast
to suppress the warning without the cost of a runtime check, but in most cases the cost doesn't matter anyway.
但是,无论您使用什么函数,您都应该决定在 中的值size_t
大于的情况下要发生什么INT_MAX
。如果您想检测它,请使用numeric_cast
或编写自己的代码进行检查。如果您以某种方式知道它不可能发生,那么您可以使用static_cast
抑制警告而无需运行时检查,但在大多数情况下,成本无关紧要。
回答by Ida
Assuming that the program cannot be redesigned to avoid the cast (ref. Keith Thomson's answer):
假设无法重新设计程序以避免强制转换(参考Keith Thomson 的回答):
To cast from size_t to int you need to ensure that the size_t does not exceed the maximum value of the int. This can be done using std::numeric_limits:
要将 size_t 转换为 int,您需要确保 size_t 不超过 int 的最大值。这可以使用std::numeric_limits来完成:
int SizeTToInt(size_t data)
{
if (data > std::numeric_limits<int>::max())
throw std::exception("Invalid cast.");
return std::static_cast<int>(data);
}
If you need to cast from size_t to double, and you need to ensure that you don't lose precision, I think you can use a narrow cast (ref. Stroustrup: The C++ Programming Language, Fourth Edition):
如果您需要从 size_t 转换为 double,并且需要确保不会丢失精度,我认为您可以使用窄转换(参考 Stroustrup:C++ 编程语言,第四版):
template<class Target, class Source>
Target NarrowCast(Source v)
{
auto r = static_cast<Target>(v);
if (static_cast<Source>(r) != v)
throw RuntimeError("Narrow cast failed.");
return r;
}
I tested using the narrow cast for size_t-to-double conversions by inspecting the limits of the maximum integers floating-point-representable integers (code uses googletest):
我通过检查最大整数浮点数可表示整数的限制(代码使用 googletest)来测试使用窄型转换进行 size_t-to-double 转换:
EXPECT_EQ(static_cast<size_t>(NarrowCast<double>(size_t{ IntegerRepresentableBoundary() - 2 })), size_t{ IntegerRepresentableBoundary() - 2 });
EXPECT_EQ(static_cast<size_t>(NarrowCast<double>(size_t{ IntegerRepresentableBoundary() - 1 })), size_t{ IntegerRepresentableBoundary() - 1 });
EXPECT_EQ(static_cast<size_t>(NarrowCast<double>(size_t{ IntegerRepresentableBoundary() })), size_t{ IntegerRepresentableBoundary() });
EXPECT_THROW(NarrowCast<double>(size_t{ IntegerRepresentableBoundary() + 1 }), std::exception);
EXPECT_EQ(static_cast<size_t>(NarrowCast<double>(size_t{ IntegerRepresentableBoundary() + 2 })), size_t{ IntegerRepresentableBoundary() + 2 });
EXPECT_THROW(NarrowCast<double>(size_t{ IntegerRepresentableBoundary() + 3 }), std::exception);
EXPECT_EQ(static_cast<size_t>(NarrowCast<double>(size_t{ IntegerRepresentableBoundary() + 4 })), size_t{ IntegerRepresentableBoundary() + 4 });
EXPECT_THROW(NarrowCast<double>(size_t{ IntegerRepresentableBoundary() + 5 }), std::exception);
where
在哪里
constexpr size_t IntegerRepresentableBoundary()
{
static_assert(std::numeric_limits<double>::radix == 2, "Method only valid for binary floating point format.");
return size_t{2} << (std::numeric_limits<double>::digits - 1);
}
That is, if N is the number of digits in the mantissa, for doubles smaller than or equal to 2^N, integers can be exactly represented. For doubles between 2^N and 2^(N+1), every other integer can be exactly represented. For doubles between 2^(N+1) and 2^(N+2) every fourth integer can be exactly represented, and so on.
也就是说,如果 N 是尾数中的位数,对于小于或等于 2^N 的双精度数,可以精确表示整数。对于 2^N 和 2^(N+1) 之间的双精度数,可以精确表示每隔一个整数。对于 2^(N+1) 和 2^(N+2) 之间的双精度数,可以精确表示每四个整数,依此类推。