【问题标题】:Convert Long Long Int to int64_t in C by Assignment通过赋值将 Long Long Int 转换为 C 中的 int64_t
【发布时间】:2021-10-02 20:03:10
【问题描述】:

以下代码通过将long long int 类型的变量分配给int64_t 类型的变量,将long long int 类型的值转换为int64_t 类型的值。这种将long long int 转换为int64_t 的方式存在哪些潜在问题?

#include <stdio.h>
#include <stdint.h>

int main (void) {

    long long int num = 9223372036854775807; // 2^63-1
    int64_t num64_t = num;
    
    printf("%lld\n", num64_t);

    return 0;
  
}

一个问题可能是 ISO/IEC 9899:1999 standard 在 p 上指定。 22, § 5.2.4.2.1,long long int 的范围至少 ±2^63-1,而int64_t 类型有正好 64 位宽度。是不是在某些机器上long long int 类型的值使用超过 64 位存储?如果num 的值大于2^63-1 或小于-(2^63-1),这可能会导致上述程序崩溃,因为num64_t 只有64 位可用。 如果这是一个问题:还有其他问题吗?更一般地说:上述方法是将long long int 类型的值转换为int64_t 类型的值的安全方法吗?如果没有,如何避免这些问题?

【问题讨论】:

  • 您可以在赋值前将值与INT64_MININT64_MAX进行比较,以确保赋值正确。

标签: c integer long-long


【解决方案1】:

一个问题可能是 ISO/IEC 9899:1999 标准在第22, § 5.2.4.2.1,long long int 的范围是至少 ±2^63-1,而 int64_t 类型有 正好 64 位宽度。

C99 已过时,但该标准的更新版本(当前为 C2017)指定了相同的内容。是的,这是一个潜在的问题:与其说是类型的大小,不如说是它们的可表示值的范围。如果您尝试将long long int 值分配给int64_t,并且该值不能表示为int64_t,则结果要么是实现定义的,要么会引发实现定义的信号。

会不会是在某些机器上 long long int 类型的值使用超过 64 位存储?

是的,这是可能的。而且long long int的范围比int64_t的范围更广。

如果num 的值大于 2^63-1 或小于 -(2^63-1),这可能会导致上述程序崩溃,因为num64_t 只有 64 位可用。

是的,如果结果是引发一个信号,那么这可能会导致程序崩溃。然而,更典型的情况是转换成功但(必然)在受让人中产生不同的值。这可能会更糟,因为您不会立即注意到这个问题。

如果这是一个问题:还有其他问题吗?更一般地说:上述方法是将long long int 类型的值转换为int64_t 类型的值的安全方法吗?

将整数值分配给任何整数类型的对象都会自动将值转换为目标类型。当分配的值在目标类型中可表示时,允许从一种整数类型转换为另一种整数类型并保留值。尽管与您的具体情况无关,但如果目标类型是无符号的,则允许并明确定义此类转换,即使原始值在无符号目标类型中不可表示也是如此。我已经描述了所有其他情况下的效果。

也就是说,不,除了已经描述的尝试将超出范围的值分配给目标有符号整数对象的后果之外,没有任何问题需要关注。

【讨论】:

  • 因此一种解决方案可能是检查 INT64_MAX == LLONG_MAX 还是 INT64_MIN
  • 是的,@MoritzWolff,或多或少。给定num 类型为long long int,您可以在将num 分配给int64_t 类型的变量之前测试是否INT64_MIN &lt;= num &amp;&amp; num &lt;= INT64_MAX。这可能涉及(自动)将INT64_MININT64_MAX 提升为类型long long int。在任何情况下,它都允许您确保只分配边界值。但是,如果尝试执行超出范围的分配,它仍然会给您留下一个问题。
  • 在可能的情况下,最好以不首先出现问题的方式选择类型。因此,例如,如果您想要 int64_t,那么始终始终使用它,而不是混入 long long int
  • +1 表示您对混合类型的评论。这个问题是在涉及将命令行参数作为输入并将结果字符串转换为 int64_t 类型的练习的上下文中出现的。当我选择使用接受字符串并返回 long long int 的函数 atoll() 时,我随后遇到了这类问题。我仍然不知道为什么会这样提出这个问题,但至少它让我想到了我们讨论的边缘情况。
猜你喜欢
  • 2011-05-08
  • 2014-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多