【问题标题】:How to convert long long to unsigned int in C/C++如何在 C/C++ 中将 long long 转换为 unsigned int
【发布时间】:2019-06-04 00:41:53
【问题描述】:

我正在使用 jannson 库从 JSON 文件中读取数据。我正在阅读的键具有unsigned int 类型的值。 Jannson 无法识别 unsigned int。因此,我将值读取为long long。如何安全地将这个 long long 值转换为 unsigned int

【问题讨论】:

  • 您可能无法这样做,因为 long long 可能会为 unsigned int 保存负数和较大的数字。您使用的是 C 还是 C++?选择一个。
  • 如何定义“安全”?如果该值肯定在unsigned int 的范围内,那么只需转换它就安全了。
  • @NicolBolas C++ 确实有其他 C 没有的转换选项,例如 static_cast
  • @NicolBolas 我不是在争论定义明确的角度,你就在那儿,但是 C++ 更喜欢 static_cast 这样的东西,以便编译器可以标记错误的转换。通常 C 不在乎,它只是按照所告诉的去做,各种丑陋的截断错误可能而且将会发生。 (int) floatX 是完全有效的,即使它对范围很广的值产生未定义的行为。
  • @NicolBolas C++ 有其他选项,例如 gsl::narrowgsl::narrow_cast,在这种情况下会被推荐,而在 C 中会有所不同。参考:stackoverflow.com/questions/52863643/…

标签: c++ c type-conversion


【解决方案1】:

如何在 C/C++ 中将 long long 转换为 unsigned int?

测试值是否在范围内。
C方案:

#include <stdbool.h>
#include <limits.h>

// return error status 
bool ll_to_u(unsigned *y, long long x) {
  if (x < 0) {
    return true;
  }
  #if LLONG_MAX > UINT_MAX
  if (x > UINT_MAX) {
    return true;
  }
  #endif
  *y = (unsigned) x;
  return false;
}

【讨论】:

  • 我认为#if 是多余的?即使它不是真的,测试仍然可以正常工作。
  • @M.M 是的,但有些编译器会发出警告。 #if LLONG_MAX &gt; UINT_MAX 避免了这种情况。
  • C 解决方案需要 吗?
  • @Myshkin &lt;stdbool.h&gt; 已添加。
【解决方案2】:

如何安全地将这个long long 值转换为unsigned int

像这样:

long long input = ...
if (input < 0)
    throw std::runtime_error("unrepresentable value");
if (sizeof(unsigned) < sizeof(long long)
&& input > static_cast<long long>(std::numeric_limits<unsigned>::max()))
    throw std::runtime_error("unrepresentable value");
return static_cast<unsigned>(input);

如果您不喜欢异常,可以使用您选择的任何其他错误处理方法。

【讨论】:

  • sizeof(unsigned)
  • 从另一方面来说,了解 K&R strlen 的实施对于教育目的很有用。
【解决方案3】:

为避免缩小转换错误,使用它更安全 - numeric_cast

numeric_cast 很容易添加到项目中,因为使用的 boost 代码只是标题 - 无需构建 boost。 这样您就可以在运行时精度丢失的情况下捕获异常。

如果安全不是主要优先事项(或者您确信 unsigned int 始终足以包含 long long 值)而不是使用:

static_cast<unsigned int>(llval)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-20
    • 2017-01-04
    • 1970-01-01
    相关资源
    最近更新 更多