使用printf跨平台打印64位整数

时间:2021-12-08 03:07:00

In Windows, it is "%I64d". In Linux and Solaris, it is "%lld".
If I want to write cross-platform printfs that prints long long values: what is good way of doing so ?

在Windows中,它是“%I64d”。在Linux和Solaris中,它是“%lld”。如果我想编写跨平台的printfs来打印很长的值:这样做的好方法是什么?

long long ll;
printf(???, ll);

4 个解决方案

#1


36  

There are a couple of approaches.

有几种方法。

You could write your code in C99-conforming fashion, and then supply system-specific hacks when the compiler-writers let you down. (Sadly, that's rather common in C99.)

你可以用符合C99的方式编写代码,然后在编译器编写器让你失望的时候提供系统特定的hacks。 (可悲的是,这在C99中很常见。)

#include <stdint.h>
#include <inttypes.h>

printf("My value is %10" PRId64 "\n", some_64_bit_expression);

If one of your target systems has neglected to implement <inttypes.h> or has in some other way fiendishly slacked off because some of the type features are optional, then you just need a system-specific #define for PRId64 (or whatever) on that system.

如果你的一个目标系统忽略了实现 或者以某种其他方式因为某些类型特性是可选的而被淘汰,那么你只需要一个特定于系统的#define用于PRId64(或其他)那个系统。

The other approach is to pick something that's currently always implemented as 64-bits and is supported by printf, and then cast. Not perfect but it will often do:

另一种方法是选择当前始终实现为64位且由printf支持然后进行强制转换的内容。不完美但通常会这样做:

printf("My value is %10lld\n", (long long)some_64_bit_expression);

#2


2  

MSVC supports long long and ll starting Visual Studio 2005.

MSVC支持long long和ll启动Visual Studio 2005。

You could check the value of the _MSC_VER macro (>= 1400 for 2005), or simply don't support older compilers.

您可以检查_MSC_VER宏的值(2005年> = 1400),或者只是不支持较旧的编译器。

It doesn't provide the C99 macros, so you will have to cast to long long rather than using PRId64.

它不提供C99宏,因此您必须使用长期而不是使用PRId64。

This won't help if you're using older MSVC libraries with a non-MSVC compiler (I think mingw, at least, provides its own version of printf that supports ll)

如果您使用较旧的MSVC库和非MSVC编译器,这将无济于事(我认为至少mingw提供了自己的支持ll的printf版本)

#3


1  

No on linux and solaris it is only incidentally that this is lld for a 64bit type. C99 prescribes simple (but ugly) macros to make these things portable PRId64. Since some windows compilers don't follow the standard you might be out of luck, there, unfortunately.

在Linux和solaris上没有,这只是偶然的,这是64位类型的lld。 C99规定了简单(但丑陋)的宏来使这些东西便携PRId64。由于某些Windows编译器不遵循标准,您可能会运气不好,不幸的是。

Edit: In your example you are using a different thing than a 64bit integer, namely a long long. This could well be 128 on some architectures. Here C99 has typedefs that guarantee you the minimum or exact width of the type (if they are implemented on the platform). These types are found with the inttypes.h header, namely int64_t for a fixe-width 64 bit type represented in two's complement. Maybe or maybe not your windows compiler has this.

编辑:在您的示例中,您使用的是与64位整数不同的东西,即长整数。在某些架构上,这可能是128。这里C99有typedef,可以保证类型的最小或精确宽度(如果它们在平台上实现)。这些类型可以在inttypes.h头文件中找到,即int64_t用于以二进制补码表示的固定宽度64位类型。也许或许不是你的Windows编译器有这个。

#4


0  

As alternative you can use code like this:

作为替代方案,您可以使用以下代码:

uint64_t currentTimeMs = ...;

printf("currentTimeMs = 0x%08x%08x\n",
            (uint32_t)(currentTimeMs >> 32),
            (uint32_t)(currentTimeMs & 0xFFFFFFFF)
    );

Or maybe:

或者可能:

printf("currentTimeMs = %u%09u\n",
            (uint32_t)(currentTimeMs / 1000000000),
            (uint32_t)(currentTimeMs % 1000000000)
    );

#1


36  

There are a couple of approaches.

有几种方法。

You could write your code in C99-conforming fashion, and then supply system-specific hacks when the compiler-writers let you down. (Sadly, that's rather common in C99.)

你可以用符合C99的方式编写代码,然后在编译器编写器让你失望的时候提供系统特定的hacks。 (可悲的是,这在C99中很常见。)

#include <stdint.h>
#include <inttypes.h>

printf("My value is %10" PRId64 "\n", some_64_bit_expression);

If one of your target systems has neglected to implement <inttypes.h> or has in some other way fiendishly slacked off because some of the type features are optional, then you just need a system-specific #define for PRId64 (or whatever) on that system.

如果你的一个目标系统忽略了实现 或者以某种其他方式因为某些类型特性是可选的而被淘汰,那么你只需要一个特定于系统的#define用于PRId64(或其他)那个系统。

The other approach is to pick something that's currently always implemented as 64-bits and is supported by printf, and then cast. Not perfect but it will often do:

另一种方法是选择当前始终实现为64位且由printf支持然后进行强制转换的内容。不完美但通常会这样做:

printf("My value is %10lld\n", (long long)some_64_bit_expression);

#2


2  

MSVC supports long long and ll starting Visual Studio 2005.

MSVC支持long long和ll启动Visual Studio 2005。

You could check the value of the _MSC_VER macro (>= 1400 for 2005), or simply don't support older compilers.

您可以检查_MSC_VER宏的值(2005年> = 1400),或者只是不支持较旧的编译器。

It doesn't provide the C99 macros, so you will have to cast to long long rather than using PRId64.

它不提供C99宏,因此您必须使用长期而不是使用PRId64。

This won't help if you're using older MSVC libraries with a non-MSVC compiler (I think mingw, at least, provides its own version of printf that supports ll)

如果您使用较旧的MSVC库和非MSVC编译器,这将无济于事(我认为至少mingw提供了自己的支持ll的printf版本)

#3


1  

No on linux and solaris it is only incidentally that this is lld for a 64bit type. C99 prescribes simple (but ugly) macros to make these things portable PRId64. Since some windows compilers don't follow the standard you might be out of luck, there, unfortunately.

在Linux和solaris上没有,这只是偶然的,这是64位类型的lld。 C99规定了简单(但丑陋)的宏来使这些东西便携PRId64。由于某些Windows编译器不遵循标准,您可能会运气不好,不幸的是。

Edit: In your example you are using a different thing than a 64bit integer, namely a long long. This could well be 128 on some architectures. Here C99 has typedefs that guarantee you the minimum or exact width of the type (if they are implemented on the platform). These types are found with the inttypes.h header, namely int64_t for a fixe-width 64 bit type represented in two's complement. Maybe or maybe not your windows compiler has this.

编辑:在您的示例中,您使用的是与64位整数不同的东西,即长整数。在某些架构上,这可能是128。这里C99有typedef,可以保证类型的最小或精确宽度(如果它们在平台上实现)。这些类型可以在inttypes.h头文件中找到,即int64_t用于以二进制补码表示的固定宽度64位类型。也许或许不是你的Windows编译器有这个。

#4


0  

As alternative you can use code like this:

作为替代方案,您可以使用以下代码:

uint64_t currentTimeMs = ...;

printf("currentTimeMs = 0x%08x%08x\n",
            (uint32_t)(currentTimeMs >> 32),
            (uint32_t)(currentTimeMs & 0xFFFFFFFF)
    );

Or maybe:

或者可能:

printf("currentTimeMs = %u%09u\n",
            (uint32_t)(currentTimeMs / 1000000000),
            (uint32_t)(currentTimeMs % 1000000000)
    );