[英]How to static cast 2D vector size() (size_t to int) in C++?
[英]How to cast the size_t to double or int C++
我的問題是
我有一個 size_t 數據,但現在我想將其轉換為 double 或 int。
如果我做類似的事情
size_t data = 99999999;
int convertdata = data;
編譯器會報告警告。 因為它可能會溢出。
你有像 boost 這樣的方法或其他一些方法來進行轉換嗎?
size_t data = 99999999;
int convertdata = static_cast<int>(data);
可能會使警告靜音(盡管原則上編譯器可以警告它喜歡的任何東西,即使有強制轉換)。
但這並沒有解決警告告訴您的問題,即從size_t
到int
的轉換確實可能溢出。
如果可能,請設計您的程序,以便您不需要將size_t
值轉換為int
。 只需將它存儲在size_t
變量中(正如您已經完成的那樣)並使用它。
轉換為double
不會導致溢出,但對於非常大的size_t
值可能會導致精度損失。 同樣,將size_t
轉換為double
沒有多大意義; 您最好將值保留在size_t
變量中。
(如果您無法避免強制轉換,R Sahu 的回答有一些建議,例如在溢出時拋出異常。)
如果您的代碼已准備好處理溢出錯誤,則可以在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);
靜態投射:
static_cast<int>(data);
您可以使用 Boost numeric_cast
。
如果源值超出目標類型的范圍,則會引發異常,但在轉換為double
時不會檢測到精度損失。
但是,無論您使用什么函數,您都應該決定在size_t
中的值大於INT_MAX
的情況下要發生什么。 如果您想檢測它,請使用numeric_cast
或編寫您自己的代碼進行檢查。 如果您以某種方式知道它不可能發生,那么您可以使用static_cast
來抑制警告,而無需運行時檢查,但在大多數情況下,成本並不重要。
假設無法重新設計程序以避免強制轉換(參考Keith Thomson 的回答):
要將 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);
}
如果您需要將 size_t 轉換為 double,並且需要確保不會丟失精度,我認為您可以使用窄轉換(參考 Stroustrup:The C++ Programming Language,第四版):
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;
}
我通過檢查最大整數浮點數可表示整數的限制(代碼使用 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);
在哪里
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);
}
也就是說,如果 N 是尾數中的位數,對於小於或等於 2^N 的雙精度數,可以精確表示整數。 對於 2^N 和 2^(N+1) 之間的雙精度數,可以精確表示每隔一個整數。 對於 2^(N+1) 和 2^(N+2) 之間的雙精度數,可以精確表示每四個整數,依此類推。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.