Преобразование __int64 в long в Windows - PullRequest
3 голосов
/ 08 февраля 2010

Как конвертировать __int64 в long в Windows (MSVC8 и MSVC6)?

Будет ли работать нормальная типизация?

Кроме того, как насчет конвертации long в __int64? Если long - отрицательное значение, оно будет работать?

Примечание. Я говорю о сценарии, в котором переменная __int64 всегда будет содержать значение длиной не более 32 бит.

Ответы [ 4 ]

5 голосов
/ 08 февраля 2010

1. Конвертировать долго в __int64

По MSDN для ключевого слова __int64:

Ключевое слово _ _int64 объявляет новый тип, 64-разрядное (8-байтовое) целое число. Как с типами int, short и long, тип _ _int64 имеет соответствующий версия без знака, поэтому _ _int64 Ключевое слово на самом деле может быть использовано для создания два типа.

В следующем примере кода показано, как объявить два 64-разрядных целых числа, одно подписано, а другое без знака:

__ int64 signature_big_int; unsigned __int64 unsigned_big_int;

__int64 подписано, и оно должно быть шире, чем long. Так что вы можете назначить long на __int64 даже без приведения типов и, конечно, signed __int64 поддерживает отрицательный long.

2. Конвертировать __int64 в long

Можно преобразовать __int64 в long, только с возможностью потери данных. Мой msvc8 только предупреждает меня о возможности потери данных.

3. Примечание

C99 определил стандартный 64-битный целочисленный тип с именем int64_t и беззнаковую версию uint64_t в stdint.h. Если вы хотите предоставить переносимый код, вы должны использовать их, но не __int64.

Обратите внимание, что в языке программирования C ++ нет стандартного 64-битного целочисленного типа, MSVC использует __int64, но в мире Linux вы обычно используете int64_t или uint64_t, тип которого определен как long long или unsigned long long в C99 stdint.h. Здесь я предполагаю, что ваш компилятор C ++ поддерживает заголовочный файл stdint.h.

3 голосов
/ 08 февраля 2010

Да, приведение типов будет в порядке, если вы можете гарантировать, что ваши значения __int64 всегда находятся в диапазоне long. Приведение в другом направлении, то есть от long к __int64, не будет проблемой независимо от используемых значений.

2 голосов
/ 08 февраля 2010

Вот небольшой тест. Явные приведения необходимы, чтобы избежать предупреждений, если они скомпилированы с /W3:

#include <limits.h>


int main( int argc, char *argv[] )
{
    __int64 i64;
    long i;

    i64 = -1;
    i = (long)i64;
    printf( "i=%d\n", i );

    i64 = INT_MAX;
    i = (long)i64;
    printf( "i=%d\n", i );

    i64 = INT_MIN;
    i = (long)i64;
    printf( "i=%d\n", i );

    i64 = i;
    printf( "i64=%I64d\n", i64 );
}

Вывод:

i=-1
i=2147483647
i=-2147483648
i64=-2147483648
0 голосов
/ 08 сентября 2013

32-битные значения могут быть присвоены 64-битным переменным без проблем, со знаком или без знака.Присвоение 64-битного значения 32-битной переменной может быть выполнено, но потеря данных возможна, если для хранения значения потребуется более 32 бит, так как оно будет усечено для соответствия меньшей переменной.

...