【问题标题】:Convert float to int64_t while preserving ordering在保留排序的同时将 float 转换为 int64_t
【发布时间】:2020-03-04 16:12:12
【问题描述】:

我的问题类似于处理正浮点值的this question

就我而言,我正在处理正负float 值,并希望将其存储在int64_t 类型中。

注意:我希望使用 memcpy 而不是依赖联合(在 C++ 中是 UB)。

【问题讨论】:

  • 你确定这是个好主意吗?你检查过sizeof(float)sizeof(int64_t)吗?
  • 我知道这些问题。只需要支持X86_64即可。
  • @jeffreyveon:你真的想要double,就像我回答的那样吗?我假设是因为你说int64_t。但是如果你使用float,int 类型应该是int32_t
  • @R..GitHubSTOPHELPINGICE:或者,如果由于某种原因需要将 32 位浮点数放入 64-位整数。这可能比转换为 double 更有效,特别是如果您想更有效地恢复 float 位模式(只需广播符号位、逻辑右移 1 和 XOR 低 31 位。不需要也做 double->float FP 转换。)
  • @PeterCordes 我实际上是在处理浮点数,所以基本上先进行float -> double 转换。如果您可以在没有转换的情况下使用代码 sn-p 添加快速答案,我将很乐意投票,其他偶然发现此问题的人也可能受益。

标签: c++ floating-point x86-64


【解决方案1】:

正如我对有关 32 位变体的链接问题的评论中所述:

...基本上,如果设置了符号位,您可以使用带符号的 int32 并反转低 31 位。如果您想要无符号但必须添加 0x80000000 偏差,则类似的方法有效。

作为代码,适配64位:

int64_t order_preserving_repr(double x)
{
    int64_t k;
    memcpy(&k, &x, sizeof k);
    if (k<0) k ^= INT64_MAX;
    return k;
}

【讨论】:

  • 只是为了确保您不会在外来系统上意外拥有 UB,我会推荐 static_assert(sizeof x == sizeof k)
  • 是的,问题是关于将float 存储在int64_t 中,因此sizeof 测试在大多数平台上可能会失败。
  • @eerorika:如果你不假设附件 F 和 IEEE 浮点表示,那么整个问题就毫无意义,这保证了大小匹配。
  • @R..GitHubSTOPHELPINGICE 然后可能会去static_assert(std::numeric_limits&lt;double&gt;:: is_iec559()) 确保函数有意义。
猜你喜欢
  • 2017-02-03
  • 1970-01-01
  • 2012-05-05
  • 1970-01-01
  • 2011-06-17
  • 1970-01-01
  • 1970-01-01
  • 2011-03-30
  • 1970-01-01
相关资源
最近更新 更多