我在说这个:
如果我们有字母'A',十进制为77,十六进制为4D.我正在寻找获得D的最快方法.
我想到了两种方式:
给定x是一个字节.
x << 4; x >> 4
x %= 16
还有其他方法吗?哪一个更快?
要在同一页面上,我们假设sizeof(int)= 4和sizeof(long)= 8.
给定一个整数数组,逻辑上将数组移位到左侧或右侧的有效方法是什么?
我正在考虑一个辅助变量,如long,它将计算第一对元素(索引0和1)的bitshift并设置第一个元素(0).以这种方式继续元素的位移(索引1和2)将是计算机,然后将设置索引1.
我认为这实际上是一种相当有效的方法,但也有缺点.我不能比特位移大于32位.我认为使用多个辅助变量会起作用,但我正在设想沿线的某个地方进行递归.
I would like to know if performing a logical right shift is faster when shifting by a power of 2
For example, is
myUnsigned >> 4
Run Code Online (Sandbox Code Playgroud)
any faster than
myUnsigned >> 3
Run Code Online (Sandbox Code Playgroud)
我很欣赏每个人的第一反应是告诉我,人们不应该担心像这样的小事,它使用正确的算法和集合来减少重要的数量级.我完全同意你的意见,但我真的想从嵌入式芯片(ATMega328)中挤出所有东西 - 我只是有一个性能转变,值得'哇喔!' 通过用位移替换除法,所以我向你保证这很重要.
使用提供的位替换字节的最低有效位的最佳方法是什么?
我知道如何检查和比较最后一位(使用例如posix ffs()函数),但我想知道是否有更好性能的解决方案,而不检查替换位是0还是1.
该示例以python编写为伪代码,但我将在C中实现工作算法:
>>> bin(0b1) # bit is '0b1'
>>> bin(128) # byte is '0b10000000'
>>> bin(129) # byte is '0b10000001'
>>> bin(128 OPERATOR 0b1) # Replace LSB with 1
'0b10000001'
>>> bin(128 OPERATOR 0b0) # Keep LSB at 0
'0b10000000'
>>> bin(129 OPERATOR 0b1) # Keep LSB at 1
'0b10000001'
>>> bin(129 OPERATOR 0b0) # Replace LSB with 0
'0b10000000'
Run Code Online (Sandbox Code Playgroud)
显然,运算符可以是一组运算,但我正在寻找最优(最快)的方法.
这个问题不是关于"我如何按位排列"我们现在如何做到这一点,我们正在寻找的是一种更快的方式,更少的CPU指令,受到DES中sbox的bitlice实现的启发
为了加快一些密码,我们希望减少排列调用的数量.主要密码函数基于查找数组执行多个按位排列.由于置换操作只是位移,
我们的基本思想是采用需要相同排列的多个输入值,并将它们并行移位.例如,如果必须将输入位1移动到输出位6.
有没有办法做到这一点?我们现在没有示例代码,因为绝对不知道如何以高效的方式实现这一目标.
我们平台上的最大值大小为128位,最长输入值为64位.因此代码必须更快,然后进行128次整个排列.
编辑
这是一个简单的8位排列示例
+---+---+---+---+---+---+---+---+
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <= Bits
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <= Input
+---+---+---+---+---+---+---+---+
| 3 | 8 | 6 | 2 | 5 | 1 | 4 | 7 | <= Output
+---+---+---+---+---+---+---+---+
Run Code Online (Sandbox Code Playgroud)
密码使用多个输入密钥.它是块密码,因此必须将相同的模式应用于输入的所有64位块.
由于每个输入块的排列相同,我们希望在一个步骤中处理多个输入块/组合多个输入序列的操作.而不是每次呼叫移动128次一位,一次移动1次128位.
EDIT2
我们不能使用线程,因为我们必须在没有线程支持的情况下在嵌入式系统上运行代码.因此,我们也无法访问外部库,我们必须保持简单C.
解
在测试并使用给定的答案后,我们通过以下方式完成:
所有这些功能都可以在我的机器上获得预期的结果.他们都在其他平台上工作吗?
更具体地说,如果x在1的补码机器上具有位表示0xffffffff或在有符号的幅度机器上具有0x80000000,那么标准对于(无符号)x的表示有何看法?
另外,我认为v2,v2a,v3,v4中的(unsigned)转换是多余的.它是否正确?
假设sizeof(int)= 4且CHAR_BIT = 8
int logicalrightshift_v1 (int x, int n) {
return (unsigned)x >> n;
}
int logicalrightshift_v2 (int x, int n) {
int msb = 0x4000000 << 1;
return ((x & 0x7fffffff) >> n) | (x & msb ? (unsigned)0x80000000 >> n : 0);
}
int logicalrightshift_v2a (int x, int n) {
return ((x & 0x7fffffff) >> n) | (x & (unsigned)0x80000000 ? (unsigned)0x80000000 >> n : 0);
}
int logicalrightshift_v3 (int x, int n) { …Run Code Online (Sandbox Code Playgroud) 我正在尝试将字节数组转换为数字,对于大数字,我看到位移是给出-ve结果.你们其中一个人可以为什么我们看到这个问题?您是否看到使用"乘法"而不是"位移"的任何缺点?
例如,
<script language="JavaScript">
var myVar = 1000000;
document.write("Bit shift Result: " + (myVar << 8));
document.write("<br>");
document.write("Multiplication Result: " + parseInt(myVar *256));
</script>
Run Code Online (Sandbox Code Playgroud)
输出:
位移结果:256000000
乘法结果:256000000
在向myVar添加一个零之后,您会看到我正在讨论的问题
<script language="JavaScript">
var myVar = 10000000;
document.write("Bit shift Result: " + (myVar << 8));
document.write("<br>");
document.write("Multiplication Result: " + parseInt(myVar *256));
</script>
Run Code Online (Sandbox Code Playgroud)
输出:
位移结果:-1734967296乘法结果:2560000000
我们正在使用Parasoft Static Analysis并启用了MISRA C 2004检查程序.
该软件是一个嵌入式系统.我们喜欢描述常量如下:
[1] #define MOTOR_ON (1 << 9)
Run Code Online (Sandbox Code Playgroud)
这将显示寄存器中的第9位应为1以打开电机.
表达式是MISRA失败,所以我们改变了它:
[2] #define MOTOR_ON (1U << 9U)
Run Code Online (Sandbox Code Playgroud)
更改转换为无符号整数常量,因为最好使用无符号整数进行移位.
语句2中的表达式仍然失败,因为右侧操作符(9U)需要检查.根据MISRA,如果右手操作符大于左手操作符的底层类型的位宽,则存在问题.
该问题的基础是1U具有基础类型unsigned char或8位.
我们写的寄存器是16位,所以理论上没有问题.
如何更改[2]中的表达式以使其通过MISRA C 2004,更喜欢不使用演员表?
我正在使用IAR Embedded Workbench和8/32位模式的ARM7TDMI处理器.
编辑1:示例代码.
void turn_on_motor(void);
#define MOTOR_ON (1U << 9U)
void turn_on_motor(void)
{
uint16_t * const p_motor_control = (uint16_t *)(0x01234567U);
*p_motor_control = MOTOR_ON;
}
Run Code Online (Sandbox Code Playgroud)
错误文本:应限制用作移位运算符的右侧操作数的常量.
来自Parasoft提供的MISRA规则文档:
Rule reports a violation if:
- the right-hand operand is a constant with negative value or with value that
exceeds the length …Run Code Online (Sandbox Code Playgroud) 我试图<<在a 上使用运算符long,如下所示:
((long) num3) << ( 2 + (long) num4)))
Run Code Online (Sandbox Code Playgroud)
这给了我以下错误:
运算符<<不能应用于long和long类型的操作数.
如果我没有转换num4为a long,则没有错误.但是,我不能把它作为一个int.还有其他方法吗?
我正在搞乱Flappy Bird克隆,我无法弄清楚以下代码的含义是什么
let birdCategory: UInt32 = 1 << 0
let worldCategory: UInt32 = 1 << 1
let pipeCategory: UInt32 = 1 << 2
let scoreCategory: UInt32 = 1 << 3
Run Code Online (Sandbox Code Playgroud)
对不起,如果这是显而易见的,我已经尝试寻找答案,但找不到它.谢谢