Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will unique values in uint64_t also be unique in int64_t

Given a vector of unique (std::uint64_t type) integers, if I cast vector of (std::uint64_t type) to vector of (std::int64_t type) integers, will it be guaranteed to be unique?

Casting like this

std::vector<std::uint64_t> unsignedVec;
std::vector<std::int64_t> signedVec( unsignedVec.begin(), unsignedVec.end() );
like image 429
veda Avatar asked May 15 '19 20:05

veda


People also ask

What is the difference between Int64 and uint64?

Int64: This Struct is used to represents 64-bit signed integer. The Int64 can store both types of values including negative and positive between the ranges of -9,223,372,036,854,775,808 to +9, 223,372,036,854,775,807 UInt64: This Struct is used to represents 64-bit unsigned integer.

What is the maximum value a uint64 can store?

The UInt64 can store only positive value only which ranges from 0 to 18,446,744,073,709,551,615. 1. Int64 is used to represents 64 -bit signed integers .

What is the range of Int64 in C?

The Int64 can store both types of values including negative and positive between the ranges of -9,223,372,036,854,775,808 to +9, 223,372,036,854,775,807 UInt64: This Struct is used to represents 64-bit unsigned integer.

What is the maximum and minimum value of Int64 in MySQL?

Minimum value of Int64: -9223372036854775808 Maximum value of Int64: 9223372036854775807 -3 0 1 3 7 UInt64: This Struct is used to represents 64-bit unsigned integer. The UInt64 can store only positive value only which ranges from 0 to 18,446,744,073,709,551,615. Example :


3 Answers

will it be guaranteed to be unique?

Formally it's implementation-defined, but on any sensible platform it should be unique.

(Especially given that int64_t has to be 2's complement if it's provided.)

Since C++20 it has to be unique.


https://en.cppreference.com/w/cpp/language/implicit_conversion#Numeric_conversions

If the destination type is signed, the value does not change if the source integer can be represented in the destination type. [Otherwise the result is implementation-defined (until C++20)] [the unique value of the destination type equal to the source value modulo 2n where n is the number of bits used to represent the destination type. (since C++20)].

like image 62
HolyBlackCat Avatar answered Oct 17 '22 06:10

HolyBlackCat


The values ending up in signedVec using

std::vector<std::int64_t> signedVec( unsignedVec.begin(), unsignedVec.end() );

will be implementation-defined in C++11 if the corresponding value in unsignedVec is larger than what std::int64_t can represent. Otherwise, the value will be the same [conv.integral]/3:

If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined.

Note: C++11 inherits the definition of std::int64_t from C99 via [headers]/4. int64_t is specified in C99 [7.18.1.1]/1 as (emphasis mine; thanks to @Bob__ for pointing this out):

The typedef name intN_t designates a signed integer type with width N, no padding bits, and a two’s complement representation.

and [7.18.1.1]/3

These types are optional. However, if an implementation provides integer types with widths of 8, 16, 32, or 64 bits, no padding bits, and (for the signed types) that have a two’s complement representation, it shall define the corresponding typedef names.

So while it is technically still implementation-defined, it is very unlikely that the values will not be unique if the code compiles (which it only will if std::int64_t is defined, as that is optional). Since int64_t is specified to have a two's-complement representation and is only defined if the implementation can support that, for the conversion to behave in any other than the expected way would be very surprising. I've never heard of a compiler where it would not behave as expected. Furthermore, as pointed out in the answer by @HolyBlackCat, the desired behavior will be required starting with C++20 [conv.integral]/3…

like image 38
Michael Kenzel Avatar answered Oct 17 '22 07:10

Michael Kenzel


With given code two possible scenario exists:

  • All elements of original vector unsignedVec are lesser than or equal to std::numeric_limits<int64_t>::max(). In this case target vector elements would be identical to original vector elements, and all their properties would be preserved.
  • There are elements in the original vector which are greater than std::numeric_limits<int64_t>::max(). In this case program behavior is not defined in the Standard, is left up to the implementation, and anything can happen.
like image 1
SergeyA Avatar answered Oct 17 '22 06:10

SergeyA