2013-04-16 33 views
2

關於在stdint.h中找到的那些定義,我希望測試將int8_t的向量或int64_t向量轉換爲std::string向量的函數。int8_t和int64_t的最小值

這裏是我的測試:

TEST(TestAlgorithms, toStringForInt8) 
{ 
    std::vector<int8_t> input = boost::assign::list_of(-128)(0)(127); 
    Container container(input); 
    EXPECT_TRUE(boost::apply_visitor(ToString(),container) == boost::assign::list_of("-128")("0")("127")); 
} 

TEST(TestAlgorithms, toStringForInt64) 
{ 
    std::vector<int64_t> input = boost::assign::list_of(-9223372036854775808)(0)(9223372036854775807); 
    Container container(input); 
    EXPECT_TRUE(boost::apply_visitor(ToString(),container) == boost::assign::list_of("-9223372036854775808")("0")("9223372036854775807")); 
} 

但是,我得到的線在Visual Studio中警告:

std::vector<int64_t> input = boost::assign::list_of(-9223372036854775808)(0)(9223372036854775807); 

如下:

warning C4146: unary minus operator applied to unsigned type, result still unsigned 

如果我改變-9223372036854775808到-9223372036854775807,警告消失。

這裏有什麼問題?關於我的原始代碼,測試正在通過。

+0

你也試過-9223372036854775808ll?正如Bo Persson所說,無論如何你都應該使用std:numeric_limits。 –

回答

10

這就像編譯器說的,-9223372036854775808不是一個有效的數字,因爲-和數字被分開處理。

您可以嘗試-9223372036854775807 - 1或使用std::numeric_limits<int64_t>::min()來代替。

+1

+ std :: numeric_limits :: min()',這是最清晰,最具表現力,最便攜的方式。 – DevSolar

+0

@DevSolar這當然更清潔,更有表現力。然而,關於可移植性,「int64_t」必須是正好64位,2的補碼錶示,這意味着它在每個地方都有完全相同的最小值。 –

+0

@JamesKanze:對,但'-9223372036854775808'是一種不可移植的方式來編寫最小值(因爲在具有2的補碼64位'long long'的實現中,它調用實現定義的無符號 - >有符號的轉換),而'std :: numeric_limits :: min()'是一種便攜的方式。我認爲'-9223372036854775807 - 1'也是不可移植的,但是在一個假設的系統中'long long'是符號量級(所以算術以一個常量表達式進行溢出並被診斷出來)是失敗的,而'int64_t'是一些擴展2的補碼整數類型。 –

3

問題是整數文字不是負數;所以-42不是具有負值的文字,而是應用於文字42-運算符。

在這種情況下,9223372036854775808超出了int64_t的範圍,所以它會被賦予一個無符號類型。由於模塊化算術的魔力,您仍然可以否定它,將它分配到int64_t,並最終得到您期望的結果;但編譯器會警告你有關無符號否定(如果你告訴它),因爲這通常是錯誤的結果。

您可以使用std::numeric_limits<int64_t>::min()來避免該警告(並使代碼更明顯正確)。

2

更改-9223372036854775808-9223372036854775807-1

問題是-9223372036854775808不是-9223372036854775808而是-(9223372036854775808)9223372036854775808不能放入一個符號的64位類型(默認爲十進制整數常量是一個符號類型),所以它反而變得無符號。將-的否定應用於未簽名類型是可疑的,因此是警告。