【发布时间】:2020-11-30 07:19:01
【问题描述】:
我正在尝试将 crc64 校验和的 uint64_t 表示形式存储为数组。
校验和总是像uint64_t res = 0x72e3daa0aa188782,所以我希望将它存储为一个数组char digest[8],其中digest[0] 是72,digest[1] 是e3...digest[7] 是82。
我尝试循环/除法来分解数字,但如果它是一个较小的整数,那会更合适,如果起点是 Base-10,因为起点是 Base-16,输出应该但是如上所述。
更新:我删除了无意义的代码,并希望我能接受所有三个答案,因为他们都按照我的要求做了。位移是我希望得到的答案,所以这就是它被接受的原因。
【问题讨论】:
-
这个问题很混乱。看起来您正在尝试将 64 位值转换为十进制,但您正在使用浮点运算来执行此操作。你很可能有错误。此外,您有一个包含 19 位数字的数组,但您正在迭代其中的 20 多个数字。如果我从您的输出中删除最后一位数字(这是未定义的行为)并转换为十六进制,我会得到
72E3DAA0AA188CEC,这很接近但在最后一位数字中显然不正确。这是意料之中的,因为使用double计算会丢失精度。 -
建议 1:不要对循环长度进行硬编码。如果你的长度是
digit,那么你应该做for (i = 0; i < digit; ++i) -
建议 2:仅使用整数运算将您的值转换为十进制,或者简单地使用
sprintf或类似的方法将其转换为字符串。有很多成熟的方法可以做到这一点,只需搜索一个 Stack Overflow 即可。 -
建议 3:为您的数字使用一个固定的缓冲区大小,在您尝试转换的任何基数中占可能最长的
uint64_t值。在转换数字时数数。通常你不需要通过计算日志等来聪明,但如果你需要这样做,它也必须用整数函数来完成。否则你会遇到类似的问题(很可能是少数极端情况),其中精度问题把你搞砸了。而且您甚至可能不知道您正在获得未定义的行为。这可能会导致难以调试的灾难性错误。 -
我并没有尝试在任何基础上进行转换,实际上,它只是这样做了,因为它是不受欢迎的行为。我正在尝试将 crc64 校验和(作为 uint64_t 返回)存储到数组中。校验和总是和上面的例子一样,所以我想将 uint64_t res = x72e3daa0aa188782 存储为一个数组 char digest[8],其中 digest[0] 为 72,digest[1] 为 e3..digest[7]是 82..
标签: arrays c data-conversion unsigned-long-long-int bit-representation