gpt4 book ai didi

mysql - MySQL 中的 BIGINT 移位

转载 作者:行者123 更新时间:2023-11-29 07:08:01 25 4
gpt4 key购买 nike

大家好,我认为这可能是一个错误,但它让我很痛苦。我在 Ubuntu Linux 服务器上使用 MySQL 5.1.41。我正在尝试编写一个函数来创建一个随机签名的 BIGINT 值。由于 RAND() 的精度太小,无法生成所有可能的 BIGINT 值,我决定尝试使用位运算符组合四个 32 位字。

我启动了 MySQL Workbench,并尝试了以下操作以查看移位运算符是否可以正确处理负数:

SELECT HEX((0x1ACE - 0x8000) << 0x10);

0x1ACE - 0x8000 是 -25906,所以如果我向左移动 16 位,我应该乘以 65536,对吧?我得到的答案是 0xFFFFFFFF9ACE0000,它是 -1697775616 或 -25906 * 65536 的符号表示。Wunderbar,有效!!!

所以我的计划是用它来生成随机签名 BIGINT 的第一个 32 位字,并使用一个简单的循环将另外三个 32 位字添加到值中,一次将这些位移动四个字节.兴奋地,我开始将以下代码放入我的函数中,使用硬编码值来测试我的计划:

DECLARE x BIGINT;
SET x = (0x1ACE - 0x8000) << 0x10;

如果我将值设置为正值,则一切正常。但是,在使用移位的负值(在本例中为 -25906)执行此计算后,我一直得到 x 为 0x7FFFFFFFFFFFFFFFF,这是带符号的 64 位整数的最大正值。我完全不知所措。 完全相同的操作生成完全不同的结果,具体取决于它是在函数中的 SET 操作中还是在 SELECT 语句中。

所以我开始弄乱 x 是有符号的还是无符号的,事情变得很奇怪。我尝试使 x 未签名并尝试了以下操作:

DECLARE x BIGINT UNSIGNED;
SET x = (0x1ACE - 0x8000);

当我这样做时,我得到的 x 等于零。不足为奇,因为 x 是无符号的并且结果是负数。然而,为了好玩,我尝试了这个:

DECLARE x BIGINT UNSIGNED;
SET x = (0x1ACE - 0x8000) << 0;

令我惊讶的是,x 被设置为 0xFFFFFFFFFFFF9ACE!

有人可以帮忙吗?我已经在一个函数上工作了几个小时,它只不过是有效地生成一个随机签名的 BIGINT,我很累,而且我对这些东西看得越多,我就越沮丧,我对它的理解就越少.任何帮助,无论是解释这里发生了什么,还是建议编写这个函数,以便它现在始终如一地工作,如果这是一个错误,如果它得到修复,将在以后的版本中得到帮助,将不胜感激!

最佳答案

好吧,我想我刚刚弄明白了。根据the documentation , 位移运算符产生无符号 64 位整数。所以当你尝试时:

DECLARE guid BIGINT;   -- signed BIGINT
SET guid = -25924; -- = 0xFFFFFFFFFFFF9ABC
SET guid = guid << 0; -- Result: 0x7FFFFFFFFFFFFFFF

发生的事情是,为了让 guid << 0 返回一个unsigned 整数,它试图将 guid 从负符号整数转换为无符号整数,结果为 0x7FFFFFFFFFFFFFFFF,然后移位它超过零位,这是一个恒等运算,结果相同 0x7FFFFFFFFFFFFFFFF。

不过,乘法 (*) 似乎对有符号数和无符号数都能正常工作。我可以通过以下方式实现我想要的结果:

DECLARE guid BIGINT;        -- signed BIGINT
SET guid = -25924; -- = 0xFFFFFFFFFFFF9ABC
SET guid = guid * 0x10000; -- = Result: 0xFFFFFFFF9ABC0000 Woot! \o/

关于mysql - MySQL 中的 BIGINT 移位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6172072/

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