- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我最近找到了that SO question .
接受的答案和大黄做出的答案都很好,但我不明白它们是如何工作的。而且我不想在我的项目中使用我不理解的代码。我知道基本的位操作是什么(移位、AND、OR 等),但我不明白这些操作组合最终如何完成它们正在做的事情。
感谢您查看这个问题,希望能对我有所帮助。
最佳答案
64 位整数 value
表示为一个 8×8 block - 让我们假设我们理解每个单元格的“内容”如下:
1 2 3 4 5 6 7 8
9 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24
25 26 27 28 29 30 31 32
33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48
49 50 51 52 53 54 55 56
57 58 59 60 61 62 63 64
虽然value
实际上顺序存储为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...
我们还说将它向左移动四 (value << 4
) 会导致
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ...
或
5 6 7 8 9 10 11 12
13 14 15 16 17 18 19 20 ...
并将其向右移动四位 (value >> 4
) 得到
0 0 0 0 1 2 3 4
5 6 7 8 9 10 11 12 ...
现在开始
uint64 reflect_vert (uint64 value)
{
value = ((value & 0xFFFFFFFF00000000ull) >> 32) | ((value & 0x00000000FFFFFFFFull) << 32);
value = ((value & 0xFFFF0000FFFF0000ull) >> 16) | ((value & 0x0000FFFF0000FFFFull) << 16);
value = ((value & 0xFF00FF00FF00FF00ull) >> 8) | ((value & 0x00FF00FF00FF00FFull) << 8);
return value;
}
在这里,0xFFFFFFFF00000000ull
-like 片段是位掩码,结合 AND 操作,从 value
中选择位.另请注意 0xFF
对应于设置了八位的一个字节,所以 0xFFFFFFFF
有效地描述了 4*8=32
选定的位。由于每一行都是 8
位长,这对应于 4
行。
具体来说,value & 0xFFFFFFFF00000000ull
选择(保留!)value
的高 32 位,即前四行,并丢弃其余的,而 value & 0x00000000FFFFFFFFull
选择低 32 位并丢弃第一个。 (它实际上并没有丢弃任何东西,而是将那些不匹配的元素/位置的值设置为零。)
类次操作
((value & 0xFFFFFFFF00000000ull) >> 32)
((value & 0x00000000FFFFFFFFull) << 32)
然后将这些位向下移动 (>> 32
) 到低 32 位的位置或向上移动 (<< 32
)。通过将它们组合在一起,
value = ((value & 0xFFFFFFFF00000000ull) >> 32) | ((value & 0x00000000FFFFFFFFull) << 32);
你已经有效地交换了它们。现在由于低 32 位对应于 block 的“下半部分”,我们只是像这样交换行:
33 34 35 36 37 38 39 40 \
41 42 43 44 45 46 47 48 |__
49 50 51 52 53 54 55 56 | |
57 58 59 60 61 62 63 64 / |
1 2 3 4 5 6 7 8 \ |
9 10 11 12 13 14 15 16 |__|
17 18 19 20 21 22 23 24 |
25 26 27 28 29 30 31 32 /
对 0xFFFF0000FFFF0000ull
执行相同操作和 0x0000FFFF0000FFFFull
, 使用宽度的变化 16
与邻居交换两行:
49 50 51 52 53 54 55 56 \__
57 58 59 60 61 62 63 64 / |
33 34 35 36 37 38 39 40 \__|
41 42 43 44 45 46 47 48 /
17 18 19 20 21 22 23 24 \__
25 26 27 28 29 30 31 32 / |
1 2 3 4 5 6 7 8 \__|
9 10 11 12 13 14 15 16 /
最后,0xFF00FF00FF00FF00ull
和 0x00FF00FF00FF00FFull
轮类 8
每隔一行交换一次,结果是
57 58 59 60 61 62 63 64 _
49 50 51 52 53 54 55 56
41 42 43 44 45 46 47 48 _
33 34 35 36 37 38 39 40
25 26 27 28 29 30 31 32 _
17 18 19 20 21 22 23 24
9 10 11 12 13 14 15 16 _
1 2 3 4 5 6 7 8
此时方 block 已成功垂直翻转。
reflect_diag
方法使用相同的方法有选择地交换位。这里要注意的是 0x0100000000000000
选择最高八位(顶行,中间左侧)位:
0000 0001 0000 0000
0000 0000 0000 0000
0000 0000 0000 0000
0000 0000 0000 0000
同时 0x0000000000000080
选择最低的八个(底行,中间右侧)
0000 0000 0000 0000
0000 0000 0000 0000
0000 0000 0000 0000
0000 0000 1000 0000
位。它们恰好是 49
位分开,所以将它们移动 49
交换他们的位置。
另一个例子,模式0x4020100804020100
选择位
0100 0000 0010 0000
0001 0000 0000 1000
0000 0100 0000 0010
0000 0001 0000 0000
而它的对应物 0x0080402010080402
选择
0000 0000 1000 0000
0100 0000 0010 0000
0001 0000 0000 1000
0000 0100 0000 0010
您会注意到,位之间的距离形成一种模式,允许整个 block 移动,使它们与彼此的原始位置对齐。
另请注意,与水平和垂直翻转版本相比,此代码不会覆盖原始值,而是组成一个新的输出。 Michiel 的代码就地进行移位并以八进制编码移位,因此 >> 010
实际上意味着 >> 8
, 020
是16
等等。
关于c++ - 关于将位图旋转 90° 的说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42329413/
我正在查看预先重写的 jQuery 代码。我无法理解以下代码。 $('body > *:not(#print-modal):not(script)').clone(); 最佳答案 此选择器匹配以下任何
所以我开始学习MySQL,我对表有点困惑,所以我想澄清一下。数据库中可以有多个表吗?例如: Database1 -Table1 -Username -Password -Table2 -Name
我在 PostgreSQL 中编写了一个函数,其代码如下: for (i = 0; i str[0][i]); values[i] = datumCopy(dat_value,
oid: 行的对象标识符(对象 ID)。这个字段只有在创建表的时候使用了 WITH OIDS ,或者是设置了default_with_oids 配置参数时出现。 这个字段的类型是 oid (和字段同
我在搜索最大连接设备数时发现了 a post大致说: 当使用 P2P_STAR 时,最大设备数量为 10,因为此 topoly 使用 Wi-Fi 热点。也就是说,如果您没有路由器。 这让我问了两个问题
我不明白为什么会这样: Printf.sprintf "%08s" "s" = Printf.sprintf "%8s" "s" - : bool = true 换句话说,我希望: Printf.sp
我正在遵循 Grails in Action 中的示例。我有一个问题,如何理解 addTo*()功能有效。 我有一个简单的域:具有以下关系的用户、帖子、标签: 用户1对M发帖 用户一对一标签 发布 M
请问为什么行 "b[0]= new Child2();"在运行时而不是在编译时失败。请不要检查语法,我只是在这里做了 class Base {} class Child1 : Base {} clas
所以我想进一步加深我对套接字的理解,但是我想首先从最低级别开始(在C语言中,而不是在汇编中大声笑) 但是,我处理的大多数站点都使用SOCK_STREAM或SOCK_DGRAM。但是我已经阅读了Beej
好吧,我对 javascript 语法了解甚少,而且我对 null 的行为感到非常困惑。关于空值有很多讨论,但我似乎无法找出问题所在!请帮我。这是脚本。 var jsonData = '';
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭5 年前。 Improve thi
问题: SeriesSum 类旨在计算以下系列的总和: 类名:SeriesSum 数据成员/实例变量: x:存储整数 n:存储术语数量 sum:用于存储系列总和的双变量 成员函数: SeriesSum
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 9 年前。 Improve this ques
今天我在 logcat 中注意到以下内容: D/OpenGLRenderer:0xa2c70600 (CardView) 上的 endAllStagingAnimators,句柄为 0xa2c9d35
如何创建值有序对的列表,例如list1 [(x, y), (x1, y1) ...].?? 学习如何创建此列表后,我需要知道如何将 x 值提供给列表中的用户输入并搜索 x 的下一个值并显示有序对 (x
我在存储过程中有以下逻辑。 这里完成了什么? 如果color为null,替换为'' IF ISNULL(@color, '') <> '' BEGIN END 最佳答案 它等同于: IF (@colo
我知道.Net中的接口(interface)定义了接口(interface)和继承它的类之间的契约。刚刚完成了一个大量使用数据访问层接口(interface)的项目,这让我开始思考。 . .有什么大不
如何防止基类方法被子类覆盖 最佳答案 您不需要做任何特别的事情:默认情况下方法是不可覆盖的。相反,如果您希望该方法可重写,则必须将 virtual 关键字添加到其声明中。 但是请注意,即使方法不可重写
我已阅读以下有关工厂模式的文章 here 请仅引用Class Registration - avoiding reflection这一部分。 这个版本在没有反射的情况下实现了工厂和具体产品之间的减少耦
我正在学习 Java 类(class),但无法完全理解下一课的内容。 目的:本课的目的是通过创建一个模拟 for-each 循环如何工作的替代方案来解释 for-each 循环的工作方式。 在上一课中
我是一名优秀的程序员,十分优秀!