C语言 在64位机器中,是否可以将long long返回值分配给int64_t而不损失精度?

7xzttuei  于 2023-08-03  发布在  其他
关注(0)|答案(3)|浏览(94)

我已经实现了下面的代码:

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<cstdlib>
#include<sys/types.h>
main()
{
    int64_t i64value1 = 0;
    int64_t i64value2 = 0;
    long long llvalue = 0;
    const char *s = "10811535359";
    i64value1 = atoll(s);
    llvalue = atoll(s);
    i64value2 = llvalue;
    printf("s : [%s]\n",s);
    printf("i64value1 : [%d]\n",i64value1);
    printf("llvalue : [%lld]\n",llvalue);
    printf("i64value2 : [%d]\n",i64value2);
}

字符串
以上程序的输出为:

s : [10811535359]
i64value1 : [-2073366529]
llvalue : [10811535359]
i64value2 : [-2073366529]


使用的编译器是:

gcc version 4.1.2 20080704 (Red Hat 4.1.2-48)


操作系统为 x86_64 GNU/Linux 2.6.18-194
由于 long long 是一个有符号的64位整数,并且在所有意图和目的上都与 int64_t 类型相同,因此逻辑上 int64_tlong long 应该是等效的类型。有些地方提到使用 int64_t 而不是 long long。但是当我查看 stdint.h 时,它告诉我为什么我会看到上面的行为:

# if __WORDSIZE == 64 
typedef long int  int64_t; 
# else 
__extension__ 
typedef long long int  int64_t; 
# endif


在64位编译器中,int64_tlong int,而不是 long long int
我的问题是,有没有一个变通方案/解决方案来将long long返回值分配给int64_t,而不会丢失64位机器的精度?
提前致谢

wqlqzqxt

wqlqzqxt1#

损失不是发生在转换中,而是发生在打印中:

printf("i64value1 : [%d]\n",i64value1);

字符串
访问int64_t参数时,将其视为int。这是未定义的行为,但通常低32位是符号扩展的。
正确的编译器警告(如gcc -Wformat)应该会对此进行警告。

8ljdwjyq

8ljdwjyq2#

吉尔斯说得对
要么使用std::cout <<,我认为应该以正确的方式处理它,或者在打印时使用printf("i64value2 : [%lld]\n",i64value2);应该解决它。
还有format macros for fixed-width integers可以正确处理这种情况,而不管int64_t的typedef是什么。即使是int_fast32_t也有替代品,否则处理起来会非常难看。
在这种情况下,它将是:

#include <cinttypes>

printf("\tvalue is %" PRId64 "\n", i64value2);

字符串

mklgxw1f

mklgxw1f3#

x86-64 ABI下-long longlong相同,也就是说是64位值。在这种情况下没有精度损失。

相关问题