我在C中有这个代码(仅供学习):
char x;
uint64_t total = 0;
for(x = 20; x < 30; x++){
total = (((((1 << x) * x) / 64) + 1) * sizeof(uint64_t));
printf("%d - %llu\n", x, total);
}
Run Code Online (Sandbox Code Playgroud)
什么是印刷品:
20 - 2621448
21 - 5505032
22 - 11534344
23 - 24117256
24 - 50331656
25 - 104857608
26 - 218103816
27 - 18446744073625665544
28 - 18446744073575333896
29 - 18446744073508225032
Run Code Online (Sandbox Code Playgroud)
为什么在x> 26时我有那些奇怪的值?我在Ubuntu 10.10 64位上的gcc 4.6.1.
我有一个高字节和一个低字节我想转换为短.
我已经实现了这个,这似乎有效,但我对它的原因有点困惑.双方high_byte并low_byte铸造成byte秒.
short word = (short)(high_byte << 8 | low_byte);
Run Code Online (Sandbox Code Playgroud)
在这段代码中,应该high_byte << 8为零吗?然后我尝试了这个:
(byte)1 << 8
Run Code Online (Sandbox Code Playgroud)
等于256,我认为应该是0.我想我显然错过了一些东西.
有人可以解释一下吗?
为什么会(-1 >> 1)导致-1?我在C工作,虽然我认为这不重要.
我无法弄清楚我错过了什么......
以下是执行计算的C程序示例:
#include <stdio.h>
int main()
{
int num1 = -1;
int num2 = (num1 >> 1);
printf( "num1=%d", num1 );
printf( "\nnum2=%d", num2 );
return 0;
}
Run Code Online (Sandbox Code Playgroud) 是否有任何标准方法将(任意)方程转换为位移操作?
我的意思是将任何不是+或 - 的东西转换成位移,所以结束方程只包含操作数<<,>>,+和 -.这样做有利于减少处理器密集度.
显然,这些结果方程只是近似值,在考虑更多订单(一阶,二阶等)时提供更好的准确性.
我已经在网上搜索了关于此的任何信息,但找不到任何信息,除了特定公式(sin,cos,inv等)的东西.
我想象的是多项式或泰勒的扩展过程,然后将其转换为位移操作.
我想通过重复每个位8次来膨胀unsigned char到a uint64_t.例如
char -> uint64_t
0x00 -> 0x00
0x01 -> 0xFF
0x02 -> 0xFF00
0x03 -> 0xFFFF
0xAA -> 0xFF00FF00FF00FF00
Run Code Online (Sandbox Code Playgroud)
我目前有以下实现,使用位移来测试是否设置了一个位,以实现此目的:
#include <stdint.h>
#include <inttypes.h>
#define BIT_SET(var, pos) ((var) & (1 << (pos)))
static uint64_t inflate(unsigned char a)
{
uint64_t MASK = 0xFF;
uint64_t result = 0;
for (int i = 0; i < 8; i++) {
if (BIT_SET(a, i))
result |= (MASK << (8 * i));
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
但是,我对C来说还是个新手,所以这个摆弄个别位的东西让我有点不同,可能会有更好的(即更有效的)方法.
编辑添加
好了,所以在尝试了表查找解决方案后,结果如下.但是,请记住,我没有直接测试例程,而是作为更大函数的一部分(确切地说是二进制矩阵的乘法),因此这可能会影响结果的结果.因此,在我的计算机上,当乘以一百万个8x8矩阵时,编译为:
gcc -O2 …Run Code Online (Sandbox Code Playgroud) float length = 32.32f;
long i = *(long*)&length ; // casting a float pointer to a long pointer...
i >>= 1; // right shift i but 1 ... or div by 2
length = *(float*)&i; // is this necessary?
Run Code Online (Sandbox Code Playgroud)
印刷长度给出:0.0
最终结果应为:16.16;
这个想法来自http://en.wikipedia.org/wiki/Fast_inverse_square_root.我试图理解代码的部分是一个浮点数被取出并在其上执行按位运算.我猜这一点是通过避免分支来提高性能?
上面的代码失败了.谁能告诉我我做错了什么?我的印象是它就像在long存储器中float操作它一样简单,这是错误的吗?
我找到了一些有趣的东西,如果我将代码更改为:
float length = 32.32f;
long i = *(long*)&length ;
i = 0x5f3759df - ( i >> 1 );
length = *(float*)&i;
Run Code Online (Sandbox Code Playgroud)
将此数字(0x5f3759df)添加到混音中.
打印出长度*100给出:17.0538 //近似16.16
尝试不同长度给出相同的结果.
例如:长度= 100; 结果是:10.3299 ?? //差不多......
我基本上试图从特定索引处的整数中删除一点.也就是说,我不想取消/清除这一点; 我实际上想剥离它,以便每个更高的位向下移动,替换其位置的相应位.在视觉上,可以将其与从数组中删除元素或从字符串中删除字符进行比较.
为清楚起见,举例说明:
1011011 (original number)
^ index = 2
0101111 (result)
10000000000000000000000000000001
^ index = 31
00000000000000000000000000000001
1111111111111111111111111111110
^ index = 0
0111111111111111111111111111111
Run Code Online (Sandbox Code Playgroud)
我充满自信地开始转移一些东西,并提出了以下Java方法......
public static int removeBit(int num, int i) {
int out = (num >>> (i + 1)) << i;
out |= (num << (32 - i)) >>> (32 - i);
return out;
}
Run Code Online (Sandbox Code Playgroud)
...除了一些极端情况外,几乎总是有效的:
10000000000000000000000000000001 (= Integer.MAX_VALUE - 1)
^ index = 31, results in:
10000000000000000000000000000001
1011011
^ index = 0, results in:
1111111
Run Code Online (Sandbox Code Playgroud)
换句话说,如果索引是0或31(最小或最高位),我的方法将输出垃圾.
我似乎无法绕过它,这就是为什么我要问: …
我已将在该代码中使用按位运算符的 JavaScript 代码转换为 Python 代码,但是当我在 JavaScript 和 Python 中执行此操作时存在一个问题
412287 << 10
Run Code Online (Sandbox Code Playgroud)
然后我在两种语言中得到422181888相同的结果。但是当我在两者中都这样做时
424970184 << 10
Run Code Online (Sandbox Code Playgroud)
然后我在 JavaScript 中的1377771520和 Python 中的435169468416两种语言中得到不同的结果
有人可以帮我吗?任何帮助,将不胜感激。
对于大多数可能溢出的操作符,Rust 提供了一个检查版本。例如,要测试加法是否溢出,可以使用checked_add:
match 255u8.checked_add(1) {
Some(_) => println!("no overflow"),
None => println!("overflow!"),
}
Run Code Online (Sandbox Code Playgroud)
这打印"overflow!". 还有一个checked_shl, 但根据文档,它只检查移位是否大于或等于self. 这意味着虽然这个:
match 255u8.checked_shl(8) {
Some(val) => println!("{}", val),
None => println!("overflow!"),
}
Run Code Online (Sandbox Code Playgroud)
被捕获并打印"overflow!",这是:
match 255u8.checked_shl(7) {
Some(val) => println!("{}", val),
None => println!("overflow!"),
}
Run Code Online (Sandbox Code Playgroud)
只是打印128,显然没有捕捉到溢出。向左移动时检查任何类型溢出的正确方法是什么?
bit-shift ×10
c ×5
c++ ×2
64-bit ×1
bit ×1
c# ×1
casting ×1
java ×1
javascript ×1
optimization ×1
or-operator ×1
performance ×1
python ×1
rust ×1