gpt4 book ai didi

c++ - 64 位整数方程的意外结果

转载 作者:搜寻专家 更新时间:2023-10-31 00:12:02 25 4
gpt4 key购买 nike

我想问一个关于以下等式的问题:

 value = (floor(((value - min) + (step / 2)) / step) * step) + min;

我用它来将传入值限制为给定无符号整数类型的最小步长。

我已经使用它一段时间并且效果很好,直到我最近发现它可以产生意想不到的结果。下面的程序证明了我的观点:

// test.cpp
#include <cstdio>
#include <cstdlib>
#include <cstdint>
#include <cinttypes>
#include <cmath>

int main(void)
{
uint64_t value = 2305913515935801433;
uint64_t min = value;
uint64_t step = 1;

uint64_t result1 = (value - min) + (step / 2);
uint64_t result2 = ((value - min) + (step / 2)) / step;
uint64_t result3 = floor(((value - min) + (step / 2)) / step);
uint64_t result4 = (floor(((value - min) + (step / 2)) / step) * step);
uint64_t result5 = (floor(((value - min) + (step / 2)) / step) * step) + min;

uint64_t result6_ = (floor(((value - min) + (step / 2)) / step) * step);
uint64_t result6 = result6_ + min;

printf("result1 = %" PRIu64 " (0x%" PRIX64 ")\n", result1, result1);
printf("result2 = %" PRIu64 " (0x%" PRIX64 ")\n", result2, result2);
printf("result3 = %" PRIu64 " (0x%" PRIX64 ")\n", result3, result3);
printf("result4 = %" PRIu64 " (0x%" PRIX64 ")\n", result4, result4);
printf("result5 = %" PRIu64 " (0x%" PRIX64 ")\n", result5, result5);
printf("result6 = %" PRIu64 " (0x%" PRIX64 ")\n", result6, result6);

return EXIT_SUCCESS;
}

在 64 位 Linux 下编译使用:

g++ -Wall --std=c++11 -o test test.cpp

结果:

result1 = 0 (0x0)
result2 = 0 (0x0)
result3 = 0 (0x0)
result4 = 0 (0x0)
result5 = 2305913515935801344 (0x2000402020202000)
result6 = 2305913515935801433 (0x2000402020202059)

如您所见,完整等式的结果 (result5) 是错误的,最后一个字节不知何故被清除了。最后的两部分结果 (result6) 是正确的。

我无法解释第五个结果失败的原因。我在这里缺少什么?

提前致谢!

最佳答案

floor 正在转换为浮点 double ,这会导致精度损失。

C++ 中典型的浮点 double 值对于小于 2 的整数的 53 次方是准确的。 64 位无符号整数可以大于该值。

关于c++ - 64 位整数方程的意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31797130/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com