C"double to num"转换代码:为什么这样写?

rad*_*ash 2 c double type-conversion low-level

我不明白以下C转换函数是如何工作的(以及为什么它们以这种方式编写); 我很确定原作者知道他在做什么:

typedef union TValue {
  uint64_t u64;
  double n;
  struct {
    uint32_t lo;    /* Lower 32 bits of number. */
    uint32_t hi;    /* Upper 32 bits of number. */
  } u32;
  [...]
} TValue;


static int32_t num2bit(double n)
{
  TValue o;
  o.n = n + 6755399441055744.0;  /* 2^52 + 2^51 */
  return (int32_t)o.u32.lo;
}

static uint64_t num2u64(double n)
{
#ifdef _MSC_VER
  if (n >= 9223372036854775808.0)  /* They think it's a feature. */
    return (uint64_t)(int64_t)(n - 18446744073709551616.0);
  else
#endif
  return (uint64_t)n;
}
Run Code Online (Sandbox Code Playgroud)
  • 难道num2bit实际上只是投了doubleint32_t?为什么要加?为什么这样写呢?
  • num2u64中提到的这个"功能"是什么?(我相信_MSC_VER意味着它是微软C编译器的代码路径).

请注意,并不总是使用这些函数(取决于CPU架构),这适用于little-endian(我解决了一些预处理器宏以简化).

链接到在线可浏览镜像(代码来自LuaJIT项目):周围的头文件(或整个项目).

每个提示都很受欢迎.

小智 10

num2bit旨在实现Lua BitOp语义,尤其是wrt.模数运算.由于LuaJIT仅适用于特定的CPU,平台和编译器,因此实现定义的行为得到了很好的控制.不要在其他任何地方使用此代码.

num2u64是MSVC的bug/misfeature的变通方法,它总是通过int64_t将double转换为uint64_t.对于数> = 2 ^ 63,这没有给出期望的结果.MS认为这种憎恶是一种"特征".咄.