首页 > 解决方案 > 乘以 64b x 32b 除以 64b 整数

问题描述

将 64b x 32b 除以 64b 整数的最快和跨平台/编译器(GCC 和 MSVC)方法是什么,例如:

uint64_t counter;
uint32_t resolution = NANOS_IN_SEC; // NANOS_IN_SEC = 1000000000
uint64_t freq;

uint64_t res = (counter * resolution) / freq; // but without overflow/losing precision

结果保证始终适合 64b。

我检查了很多答案,但所有答案都解决了 64b x 64b 乘法,而且速度很慢。

当我们可以假设第二个操作数仅为 32b 时,是否有解决方案如何降低代码复杂性?

标签: cmathlong-integer

解决方案


我最终得到了具体的解决方案,它甚至可以接受高于 32b 的频率。

static uint64_t counter_and_freq_to_nanotime(uint64_t counter, uint64_t freq)
{
    uint32_t div = 1, freq32;
    uint64_t q, r;

    while (freq >= (1ull << 32)) {
        freq /= 2;
        div *= 2;
    }
    freq32 = freq;

    q = counter / freq32;
    r = counter % freq32;
    return (q * NANOS_IN_SEC + (r * NANOS_IN_SEC) / freq32) * div;
}

快速基准测试(E5-2699v4,Win7 x64):

  • MFllMulDiv: ~50 纳秒
  • 这个解决方案:~1.5 ns

推荐阅读