Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Smallest values for int8_t and int64_t

Tags:

c++

With regard to to those definitions found in stdint.h, I wish to test a function for converting vectors of int8_t or vectors of int64_t to vectors of std::string.

Here are my tests:

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"));
}

However, I am getting a warning in visual studio for the line:

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

as follows:

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

If I change -9223372036854775808 to -9223372036854775807, the warning disappears.

What is the issue here? With regard to my original code, the test is passing.

like image 790
Baz Avatar asked Apr 16 '13 09:04

Baz


People also ask

What is int64_t?

A long on some systems is 32 bits (same as an integer), the int64_t is defined as a 64 bit integer on all systems (otherwise known as a long long). Portability may be affected using long, but using int64_t looks like it was created to increase portability.

What is the difference between Int and int32_t?

In C and C++, int has at least 16 bits. Usually, on common 32-bit and 64-bit architectures, it has 32 bits. The language standards permit it to have any size greater or equal to 16 bits. On the other hand, int32_t has exactly 32 bits.

What is int32_t in C?

On one machine, it might be 32 bits (the minimum required by C). On another, it's 64 bits. What do you do if you want an integer type that's precisely 32 bits long? That's where int32_t comes in: it's an alias for whatever integer type your particular system has that is exactly 32 bits.

What is int_fast16_t?

int_fast16_t is most efficient type in speed with at least the range of a 16 bit int. Example: A given platform may have decided that int should be 32-bit for many reasons, not only speed. The same system may find a different type is fastest for 16-bit integers.


2 Answers

It's like the compiler says, -9223372036854775808 is not a valid number because the - and the digits are treated separately.

You could try -9223372036854775807 - 1 or use std::numeric_limits<int64_t>::min() instead.

like image 178
Bo Persson Avatar answered Sep 30 '22 19:09

Bo Persson


The issue is that integer literals are not negative; so -42 is not a literal with a negative value, but rather the - operator applied to the literal 42.

In this case, 9223372036854775808 is out of the range of int64_t, so it will be given an unsigned type. Due to the magic of modular arithmetic, you can still negate it, assign it to int64_t, and end up with the result you expect; but the compiler will warn you about the unsigned negation (if you tell it to) since that can often be the result of an error.

You could avoid the warning (and make the code more obviously correct) by using std::numeric_limits<int64_t>::min() instead.

like image 45
Mike Seymour Avatar answered Sep 30 '22 18:09

Mike Seymour