天道酬勤,学无止境

Binary Right Shift, Given Only Addition

I am working on a project where I am reading memory locations and need to output their hex value in ASCII.

The language gives me a 16 bit word length, so I have a need to divide to grab a nibble at a time to convert to hex. Unfortunately, the language only offers and, or, not, and add for mathematical/logical functions.

I've figured I can create the desired effect by left shifting and testing for a negative flag to add a 1 to the end after shifting, but I'm figuring there has to be a better method for doing this.

Any insight would be appreciated.

评论

Using AND you can set all bits to zero except the last significant nibble:

0101010111010101
0000000000001111 AND
----------------
0000000000000101

By shifting the whole thing right, you can read the next nibble:

0101010111010101 SHR 4
----------------
    010101011101
0000000000001111 AND
----------------
0000000000001101

Is that of any use to you?

Do you have an add with carry? Instead of the test for negative add the bit off the end and add a zero with carry to put it back on the right. doesnt really save much. So far I cant think of another solution, shift left, test a bit, if set add 1 to something and shift that something:

uint a,b,i;

b=0;
for(i=0;i<4;i++)
{
   b=b+b;
   if(a&0x8000) b+=1;
   a=a+a;
}

If uint above was 16 bits then the above would give you a right shift of 12. a would be destroyed in the process to create b, as written.

You can try it in reverse: instead of trying to implement the right shift, you can use brute force. Here is an example for highest nibble:

unsigned rez, tmp;
for (rez = 0, tmp = some_word & 0x0FFF; tmp != some_word; rez++, tmp += 0x1000);

So the original method I used worked. I also came up with another, incase anyone ever has this problem again.

I built a subroutine that evaluates 4 bits at a time and creates a number based on the evaluation, for some C style pseudo code it looks like this:

16bitSignedInt bin; //binary being analyzed
int value; //number being built

for (int i = 0; i < 4; i++) // while 0-3, for each nibble of the 16 bits
{
   if (bin.bit15 = 1)
      value += 8; // dominate bit in nibble

   bin <<= 1; // left shift 1

   if (bin.bit15 = 1)
      value += 4; // 2nd bit in nibble

   bin <<= 1; // left shift 1

   if (bin.bit15 = 1)
      value += 2; // 3rd bit in nibble

   bin <<= 1; // left shift 1

   if (bin.bit15 = 1)
      value += 1; // last bit in nibble

   bin <<= 1; // left shift 1

   //do work with value
}

Crude, but effective.

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 深入理解计算机系统(2.6)------整数的运算
    深入理解计算机系统(2.6)------整数的运算   前面两篇博客我们详细讲解了计算机中整数的表示,包括有符号和无符号(补码编码)的详细介绍。那么这篇博客我们将对它们的运算有个详细的了解。   在讲解之前首先看下面的一个程序,看看输出结果是啥? #include <stdio.h> int main() { int i = 2147483647; printf("%d\n",i+1); printf("%d\n",i+i); return 0; }   结果是:      我们预期的:   i+1 = 2147483647 + 1 = 2147483648   i+i = 2147483647 + 2147483647 = 4 294 967 294   为什么程序中的结果和我们数学中的常识会有这么大的区别?两个正数相加得到负数。这就需要我们理解计算机中整数的运算原理。 1、计算机整数运算的局限   我们知道计算机是用二进制序列来表示数的。而二进制序列的长度是和计算机本身的字长有关。不同的数据类型定义的二进制序列长度不一样,即不同的数据类型表示数的大小范围是不一样的。但是不管是什么数据类型,它定义的二进制序列长度是有限的,即它表示的数的大小范围是有限的。   所以两个数做运算,如果结果超出了定义数据类型所表示数的大小范围,那么结果将会出现失真。而且这个失真的结果也不是随机的
  • leetcode经典题目(10)--位运算
    位运算的操作对象只能是整型或字符型数据。 位求反~:将运算对象逐位求反生成一个新值,将1置为0,将0置为1. 与(&):两个都为1,结果才为1; 或(|):只要一个为1,结果就为1; 异或(^):两个相同,结果为0,两个不同,结果为1. 左移运算符<<:m<<n表示把m左移n位。在左移n位的时候,最左边的n位将被丢弃,同时在最右边补上n个0; 右移运算符>>:m>>n表示把m右移n位。在右移的时候,最右边的n位将被丢弃。如果数字是一个无符号数值,则用0填补最左边的n位,如果数字是一个有符号数值,则用数字的符号位填补最左边的n位。也就是说,如果是正数,最左边补n个0,如果是负数,最左边补n个1. 这里介绍一下负数的二进制表示方法: 原码:一个正数,按照绝对值大小转换成的二进制数;一个负数按照绝对值大小转换成的二进制数,然后最高位补1,称为原码。 反码:正数的反码与原码相同,负数的反码为对该数的原码除符号位外各位取反。 补码:正数的补码与原码相同,负数的补码为反码的最后一位加1,即对该数的原码除符号位外各位取反,然后在最后一位加1. 例如:(int类型的数占4字节,即32位,所以二进制表示的前面有很多0) -5的原码为:10000000 00000000 00000000 00000101; -5的反码为:11111111 11111111 11111111 11111010;
  • LeetCode——190.颠倒的二进制位
    颠倒给定的 32 位无符号整数的二进制位。 示例 1: 输入: 00000010100101000001111010011100 输出: 00111001011110000010100101000000 解释: 输入的二进制串 00000010100101000001111010011100 表示无符号整数 43261596, 因此返回 964176192,其二进制表示形式为 00111001011110000010100101000000。 示例 2: 输入:11111111111111111111111111111101 输出:10111111111111111111111111111111 解释:输入的二进制串 11111111111111111111111111111101 表示无符号整数 4294967293, 因此返回 3221225471 其二进制表示形式为 10101111110010110010011101101001。 提示: 请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。 在 Java 中,编译器使用二进制补码记法来表示有符号整数。因此,在上面的 示例 2 中,输入表示有符号整数 -3,输出表示有符号整数
  • 力扣解题思路:位运算系列
    交换两个整数 思路:给定a,b用位运算交换两个数的值: a = a ^ b; b = a ^ b;//b = a ^ b ^ b (这里a,b是初始a,b) a = a ^ b;//a = a ^ b ^ a ^ b ^ b (这里a,b是初始a,b) 461.汉明距离 思路:对两个数进行异或操作,位级表示不同的那一位为 1,统计有多少个 1 即可。不断的判断最低位是否为1,为一则计数加一,然后将该数右移一位: public int hammingDistance(int x, int y) { int z = x ^ y; int cnt = 0; while(z != 0) { if ((z & 1) == 1) cnt++; z = z >> 1; } return cnt; } 当然,还有一种比较简单的方法,z&(z-1)操作可以每次消去z中的一个1,所有1消去完全后z就等于0: while (z != 0) { z &= (z - 1); cnt++; } 另外,还可以调用相应的API: Integer.bitCount(x ^ y) 这一题和牛客:二进制中1的个数相似,这里题目中负数用补码表示。 补码是这样的: 下面求-9 补码:先减一:0000 1001 - 1 = 0000 1000; 再取反:1111 0111。 所以有:-9 补码 = 1111 0111。
  • 详解计算机内部存储数据的形式---二进制数
    详解计算机内部存储数据的形式—二进制数 前言 要想对程序的运行机制形成一个大致印象,就要了解信息(数据)在计算机内部是以怎样的形式来表现的,又是以怎样的方法进行运算的。在 C 和 Java 等高级语言编写的 程序中,数值、字符串和图像等信息在计算机内部都是以二进制数值的形式来表现的。也就是说,只要掌握了使用二进制数来表示信息的方法及其运算机制,也就自然能够了解程序的运行机制了。那么,为什么计算机处理的信息要用二进制数来表示呢? 一、用二进制数表示计算机信息的原因 计算机内部是由  IC(集成电路( Integrated Circuit) )这种电子部件构成的。 CPU( 微处理器) 和内存也是 IC 的一种。IC 有几种不同的形状,有的像一条黑色蜈蚣, 在其两侧有数个乃至数百个引脚; 有的则像插花用的针盘, 引脚在 IC 内部并排排列着。== IC 的所有引脚, 只有直流电压0V 或 5VB 两个状态==。 也就是说, IC 的一个引脚, 只能表示两个状态。IC 的这个特性, 决定了计算机的信息数据只能用二进制数来处理。 计算机处理信息的最小单位——位, 就相当于二进制中的一位。 位的英文 bit 是二进制数位( binary digit) 的缩写。8 位二进制数被称为一个字节位是最小单位,字节是==(信息的)基本单位==。用字节单位处理数据时, 如果数字小于存储数据的字节数
  • 运算符与表达式
    运算符是一些特定的符号,允许对常量、变量及式子施加某种操作。 运算符相当于自然语言中的动词,那些被操作的常量,变量及式子被称为操作数,不同的运算符对参与运算的操作数和类型可能也有不同的要求。 此外,与数学上一样,java中的运算符也具有优先级。若多个运算符出现在同一式子中,则优先级高的先运算,对于优先级相同的运算符,则视运算符的结合性。 优先级运算符1()(显式先运算,方法调用) [] . ::(方法引用)2! + - ~ ++ – ()(强制转换)3* / %4+ -5<< >> >>>6< <= > >= instanceof7== !=8&9^10I11&&12II13?:14= += -= *= /= %= &= ^= I= <<= >>= >>>= 说明: 优先级从高到低排列——优先级数字越小,优先级越高。优先级为2的运算符是一元的——只对一个常量,变量或式子进行运算,优先级为13的运算符是java中唯一的三元运算符,其余都是二元运算符。结合性是指多个具有相同优先级的运算符出现在同一个式子中时,运算所采取的方向,大部分运算符的结合性都是从左向右。较为典型的从右向左的运算符是负号,如式子:“3±4” 等价于“3+(-4)” 赋值运算符 赋值运算符是使用频率最高的运算符之一,其功能是将某个常量,变量或式子的值赋给某个变量。赋值运算符具体包含两种:简单赋值运算符和复合赋值运算¬
  • 计算机组成原理知识点汇总(考研用)——第二章:数据的表示和运算
    计算机组成原理知识点汇总(考研用)——第二章:数据的表示和运算  本文参考于《2021年计算机组成原理考研复习指导》(王道考研),《计算机组成原理》  思维导图: 文章目录 计算机组成原理知识点汇总(考研用)——第二章:数据的表示和运算2.数据的表示和运算2.1 数制与编码 2.1.1 进位计数制及其相互转换  1.进位计数法  2.不同进制数之间的相互转换  2.1.2 真值与机器数 2.1.3 BCD码(此部分大纲已删除) 2.1.4 字符与字符串  1.字符编码ASCII码  2.汉字的表示和编码  2.1.5 校验码(大纲已删除)  1.奇偶校验码  2.海明(汉明)校验码  3.循环冗余校验(CRC)码 2.2 定点数的表示与运算 2.2.1 定点数的表示  1.无符号数与有符号数的表示  2.机器数的定点表示  3.原码、补码、反码、移码  2.2.2 定点数的运算  1.定点数的移位运算  2.原码定点数的加减法运算  3.补码定点数的加减法运算  4.符号拓展  5.溢出概念与判别方法  6.定点数的乘法运算  7.定点数的除法运算  2.2.3 C语言中的整数类型及类型转换  1.有符号数和无符号数的转换  2.不同字长整数之间的转换  2.2.4 数据的存储和排列  1.数据的大端方式和小端方式存储  2.数据按边界对齐方式存储 2.3 浮点数的表示与运算 2
  • 2 计算机组成原理第二章 数据的表示和运算 定点数运算 浮点数运算
    文章目录 1 进制转换2 定点数表示及其运算2.1 定点数表示2.1.1 真值→补码2.1.2 补码→真值2.1.3 [XT]补 →[-XT]补2.1.4 真值、原码、反码、补码转换关系图形总结2.2.4 移码 2.2 定点数运算2.2.1 移位运算2.2.2 定点数加减运算2.2.3 溢出判断判溢出方法一判溢出方法二判溢出方法三 3 浮点数及其运算3.1 浮点数表示3.2 浮点数规格化3.3 规格化浮点数的特点3.4 IEEE754 标准3.5 浮点数加减3.5.1 浮点数的加减运算实例3.5.2 舍入 3.6 浮点数强制类型转换 1 进制转换 任意进制→十进制 已知K、r、n 按权展开相加法 十进制→任意进制 除基取余法: 乘基取整法: 进制之间的转换 分组转换: 2n进制之间的转换:二进制、四进制、八进制、十六进制 二进制一>四进制、八进制、十六进制n位一组,每组转换成对应进制的符号,位数不够补左边最高位0和右边最低位0 四进制、八进制、十六进制一>二进制 每位写成对应的二进制形式 BCD码 用途:可以实现二进制,十进制的快速转换(一一对应) 8421码,4位一组的二进制表示十进制对应的符号 01234567890000000100100011010001010110011110001001 遇到8421码某组上的计算产生超过1001时,需进行加6(0110)进行结果修正 2
  • Java的按位相乘和加法(Bitwise Multiply and Add in Java)
    问题 我有做乘法和加法的方法,但是我只是无法理解它们。 它们都是来自外部网站,而不是我自己的: public static void bitwiseMultiply(int n1, int n2) { int a = n1, b = n2, result=0; while (b != 0) // Iterate the loop till b==0 { if ((b & 01) != 0) // Logical ANDing of the value of b with 01 { result = result + a; // Update the result with the new value of a. } a <<= 1; // Left shifting the value contained in 'a' by 1. b >>= 1; // Right shifting the value contained in 'b' by 1. } System.out.println(result); } public static void bitwiseAdd(int n1, int n2) { int x = n1, y = n2; int xor, and, temp; and = x & y; xor = x ^ y; while (and != 0) { and
  • 笔试面试高频算法题总结
    经中遇到的题: 1、数组的逆序数 2、LRU //hashMap加双向链表,双向链表有头尾节点, 3、最长回文序列 leetocde 5 4、矩阵中的最长递增路径,可以上下左右一起都走; leetcode329 5、判断一个二叉树是另一个二叉树的子树 6、归并排序的时间复杂度 // NlongN 7、求给出01矩阵中的最大正方形面积(全为1) lc221 8、求二叉树中距离最远的节点 leetcode543 9、判断字符串是否为合法IPV4地址 lc468 10、数组值为1-n,各出现一次,先加入x(x也是1-n的范围),找出x 11、给定n,计算15n,不用+*/ 12、给定字符数组chars,将其右移n位 13、100层楼,只有两个鸡蛋,找出鸡蛋会在哪一层楼被摔碎 14、reverse linked list in a group of k 15、如何空间O(0)实现两个数的互换 16、IP地址的Regex 17、the longest path in a binary tree lc124 18、the largest consecutive sum in an array 19、LeetCode 41 Find mis sing positive 20、给一个小于一亿的中文数字字符串,转化成数字格式 21、一个数组,把所有的0都移动到末尾,还要保持顺序不乱 维持临界点j
  • 计算机组成原理学习笔记————定点运算,二进制的加减运算及指令
    定点运算 计算机中的字由位组成,字又是用二进制表示,那么我们该如何进行二进制的加减乘除运算呢?要搞清这个问题,首先得知道计算机中实数和浮点数的表示方法,定点表示和浮点表示等,详情见我专栏中另一篇博文。 弄清楚了数在计算机中的表示方法之后,我们先来看一下移位运算。 移位运算 移位就是将一个数中每个位上的数向左或向右移动。十进制中比如15左移一位变成150,右移一位变成1.5 。 因此十进制中数相对于小数点左移n位时相当于乘以10n ,右移n位则除于10n 计算机中小数点的位置是事先约定的,因此,二进制表示的机器数在相对于小数点移动n位时就相当于乘以或除以2n 在左移或右移n位,必然会使其n位低位或n位高位出现空位,那么,该对这些空位补0还是补1呢? 这与机器数采用有符号数还是无符号数有关。 对于无符号数,采用的逻辑一位,直接对空位补0,而对于有符号数的移位称为算术移位,要根据符号和表示方式而定 算术移位规则 下图给出三种不同码制的数,分别对应正整数和负整数移位后的添补规则。 无论是正数还是负数,移位后其符号位均不变。 从图中可以得出以下结论: 机器数为正时,不论是左移还是右移,添补代码均为0。 由于负数的原码数值部分与真值相同,故在移位时只要使符号位不变,其空位均添0 即可。 由于负数的反码各位除符号位外与负数的原码正好相反,故移位后所添的代码应与原码 相反,即全部添1。 分析任意*
  • Java_表达式和运算符(算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符和三元运算符)
    Java_运算符和表达式 运算符算术运算符:+、-、*、/、 %、++、--加法(+)除法(/)取余(%) 关系运算符:<、>、<=、>=、==、!=逻辑运算符:&、|、!、^、&&、||位运算符:&(位与)、|(位或)、^(异或)、~(取非)、>>(右移)、<<(左移)、>>>(无符号右移)Integer.toBinaryString() 一个整数的二进制表达&(位与)、|(位或)、^(异或)、~(取非)<<(左移)、>>(右移)>>>(无符号右移) 赋值运算符:=、+=、-=、*=、/=、%三元运算符:? 表达式 运算符 算术运算符:+、-、*、/、 %、++、– 加法(+) 可以表示数值的相加可以表示字符串的联接 eg: “123”+“abc” —> “123abc”把非字符串转换成字符串 eg: “x”+123 —> “x123”整数变量的运算结果至少是int型 eg: byte b3=b1+b2; // error,至少为int型如果有一个整数变量是long型,那么运算结果是long型 public class Demo { public static void main(String[] args) { System.out.println(123); System.out.println('A'); System.out.println(1+3); System
  • 【LeetCode 笔记】二进制 + 位运算
    位运算 1290. 二进制链表转整数191. 位1的个数1356. 根据数字二进制下 1 的数目排序136. 只出现一次的数字389. 找不同190. 颠倒二进制位总结关于C语言位运算位运算的优点 1290. 二进制链表转整数 给你一个单链表的引用结点 head。链表中每个结点的值不是 0 就是 1。已知此链表是一个整数数字的二进制表示形式。 请你返回该链表所表示数字的 十进制值 。 输入: head = [1,0,1] 输出: 5 解释: 二进制数 (101) 转化为十进制数 (5) 输入: head = [0] 输出: 0 提示: 链表不为空。链表的结点总数不超过 30。每个结点的值不是 0 就是 1。 解题思路 采用位运算,result << 1 就相当于 result * 2, result |= 1(result |= 0) 相当于 result++(不变) 注: x & 0 = 0 (与运算,一假则假),x | 1 = 1(或运算,一真则真) /** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ int getDecimalValue(struct ListNode* head){ struct ListNode*
  • 计算机组成原理 定点运算-移位、加、减、乘、除(详细解析-看完就会)
    定点运算 一、移位运算 1.移位运算的意义: 计算机中的移位是数据相对于小数点移位(左移或右移),数据移动,小数点位置不发生变化 2.在平常,数值移位 左移:绝对值扩大 右移:绝对值缩小 3.在计算机中二进制移位 左移:数值绝对值变为原来2倍 右移:数值绝对值变为原来1/2倍 4.算术移位规则 有符号位的移位 左移1位:机器数对应真值的绝对值变为原来2倍 右移1位:机器数对应真值的绝对值变为原来1/2倍 5.移位过程中,如何填补空位 负数:数值部分和真值相同 6.逻辑移位与算术移位 无符号数的移位 逻辑左移 低位添0,高位移丢 逻辑右移 高位添0,低位移丢 例如: 01010011 逻辑左移 所有位都参加移位操作 高位0移丢,最低位添0 :10100110 算术左移 第一个0表示符号位,这个数为正数,符号位不参与移位,移位的是后面的数据00100110 例如: 10110010 逻辑右移 所有位都参加移位操作 空出的最高位补0,最低位丢弃01011001 算术右移 最高位不参与移位,符号位,表示负数,右移左侧空出最高位添1,右侧0丢弃11011001 二、加法和减法运算 1.补码加减法运算公式 在计算机中 (1)加法 A+B整数:【A】补+【B】补=【A+B】补(mod 2^(n+1)) A+B小数:【A】补+【B】补=【A+B】补(mod 2) (2)减法: A-B=A+(-B)
  • 组成原理---运算方法与运算器
    文章目录 定点数的加减运算及实现补码加减运算及运算器补码加减运算方法补码加减运算的溢出判断补码加减运算器的实现 机器数的移位运算逻辑移位算术移位循环移位移码加减运算与判溢 十进制加法运算 定点数的乘法运算及实现原码乘法及实现原码乘法算法 补码乘法及实现补码乘法算法补码乘法的硬件实现 阵列乘法器绝对值阵列乘法器补码阵列乘法器 定点数除法运算及实现原码除法及实现原码除法算法原码除法的硬件实现 补码除法及实现补码除法算法补码除法的硬件实现 阵列除法器 定点运算器的组成与结构定点运算器的组成定点运算器的内部总线结构与通路标志寄存器 浮点运算及运算器浮点加减运算浮点乘法运算浮点除法运算浮点运算器 浮点运算器举例80X87 算术协处理器80387 的性能80387 的结构 浮点运算流水线 定点数的加减运算及实现 加法运算按从右到左的顺序一位一位地求和,并将进位累加到左侧相邻的高位。而减法则是通过加法来实现的:先将减数求补,然后加上被减数。对于原码、反码机器数的加减运算过程均较为复杂,通常不采用它们进行定点数的加减运算。 目前的计算机系统普遍采用补码实现整数加减运算,在浮点数的运算中,还用移码实现阶码的加减运算。 补码加减运算及运算器 补码加减运算方法 补码的加减运算的公式是: [X+Y]补 = [X]补 + [Y]补 (mod 2 n+1) [X-Y]补 = [X]补 + [-Y]补 (mod
  • JavaScript中所有二进制运算符的列表(List of all binary operators in JavaScript)
    问题 我试图了解JavaScript中的二元运算符(仅二元运算符)可能实现的功能。 到目前为止,我发现的二进制运算符的列表如下。 它们主要来自此列表,但是有什么遗漏吗? 请注意,根据上面列出的源,我只专门使用二进制运算符,根据上面列出的源,这些运算符被定义为与两个对象一起使用的二进制运算符(这是正确的吗?)。 我还从@zessx添加了其他内容。 + //Add - //Subtract / //Divided by * //Multiple % //Modulus < //Less than > //Greater than & //AND | //OR ^ //XOR ~ //Invert each bits << //Move all bits onto the left >> //Move all bits onto the right >>> //Move all bits onto the right and fill left end with 0 回答1 您可以在规范的表达式一章中找到完整列表。 因为最“正常”的运算符是二进制的(请参阅Wikipedia的定义),所以它们没有明确列出(例如一元和三进制的运算符)。 他们是: 乘法运算符 *运算符 /运算符 %运算符加法运算符加法运算符( + ) 减法运算符( - ) 按位移位运算符左移运算符( << )
  • 在C#中,两个左尖括号“ <<”是什么意思?(What do two left-angle brackets “<<” mean in C#?)
    问题 基本上是标题中的问题。 我正在看MVC 2源代码: [Flags] public enum HttpVerbs { Get = 1 << 0, Post = 1 << 1, Put = 1 << 2, Delete = 1 << 3, Head = 1 << 4 } 我只是想知道双左尖括号<<作用。 回答1 那将是按位左移运算符。 对于每个左移,该值将有效地乘以2。因此,例如,写入value << 3将使该值乘以8。 它真正在内部执行的操作是将值的所有实际位都移到一位。 因此,如果您的值是12(十进制),则二进制值为00001100 ; 将其左移一位将变成00011000或24。 回答2 当你写 1 << n 您将位组合000000001左移n次,然后将n放入2的指数中: 2^n 所以 1 << 10 真的是 1024 对于说5项的清单,您的for将循环32次。 回答3 它称为left-shift运算符。 看一下文档 左移运算符使第一个操作数中的位模式向左移位第二个操作数所指定的位数。 移位操作腾出的位为零。 这是逻辑上的移位,而不是移位和旋转操作。 演示left-shift运算符的简单示例: for (int i = 0; i < 10; i++) { var shiftedValue = 1 << i; Console.WriteLine(" 1 << {0} = {1}
  • 使用按位运算符相乘(Multiplying using Bitwise Operators)
    问题 我想知道如何使用按位运算符将一系列二进制位相乘。 但是,我有兴趣这样做以找到二进制值的十进制小数值。 这是我正在尝试做的一个例子: 鉴于,说:1010010, 我想使用每个单独的位,以便将其计算为: 1*(2^-1) + 0*(2^-2) + 1*(2^-3) + 0*(2^-4)..... 尽管我对在 ARM 汇编中执行此操作很感兴趣,但在 C/C++ 中使用示例仍然会有所帮助。 我正在考虑用一个计数器执行一个循环,每次循环迭代时,一个计数器将递增,该值将逻辑左移,以便取第一位,并乘以 2^-计数器。 但是,我不完全确定我将如何仅获得第一个位/MSB 进行乘法,而且我对如何将该值乘以基数 2 到某个负幂感到困惑。 我知道逻辑左移会将它与基数相乘,但那些通常具有正指数。 前任。 LSL r0, 2 表示 r0 中的值将乘以 2^2 = 4。 提前致谢! 回答1 听起来你走在正确的轨道上......就去做吧。 如果我有这些二进制数,我将乘以 abcd * 1011 ======= 其中 a, b, c, d 只是位,1 或 0,这些都无关紧要,你会明白为什么 如您所知,1011 是 1*(2^0)+1(2^1)+0*(2^2)+1(2^3)。 就像小学数学一样,但更简单,因为我们只关心 1 和 0 而不是 9 比 0.. abcd * 1011 ======= abcd
  • 剑指offer总结-笔记
    1.unshift() push():在数组末尾添加元素 pop:删除数组末尾第一个元素,并返回这个元素 unshift:在数组开头添加元素 shift:删除数组开头的第一个元素,并返回这个元素 2.slice() arrayObject.slice(start,end) 返回从start到end(不包括end)的元素 3.动态规划 递归效率不高 动态规划效率较高 (1)数组版动态规划 function dynFib(n) { let val = []; for(let i = 0; i <= n; ++i){ val[i]=0; } if(n ===1 || n === 2){ return 1; } else { val[1] =1; val[2] = 2; for(let i = 3; i <= n; ++i){ val[i] = val [i-1] +val[i-2] ; } } return val[n-1] } (2)迭代版动态规划 function iterFib(n) { let last = 1; let nextLast = 1; let result = 1; for (let i = 2; i < n; ++i) { result = last + nextLast; nextLast = last; last = result; } return
  • 数据结构——复习八(查找)
    8.1 查找表的存储:线性表、索引结构、二叉树和哈希表。 对查找表进行的操作主要有:查找、增加和删除元素。其中最主要的运算是进行查找(检索)。 查找方法评价 (1)查找速度 (2)占用存储空间多少 (3)算法本身复杂程度 (4)平均查找长度ASL(Average Search Length):为确定记录在表中的位置,需和给定值进行比较的关键字的个数的期望值叫查找算法的平均查找长度。 平均查找长度(ASL) 8.2静态查找表 8.2.1顺序查找表 顺序查找 int seqsrch(int r[],int n,int k) { int i=n; r[0]=k; while(r[i]!=k) i--; return i; } 顺序查找方法的ASL 比较次数: 查找第n个元素: 1 查找第n-1个元素:2 查找第i个元素: n+1-i 查找失败: n+1 8.2.2有序表的查找 折半查找(二分法查找) int binsrch(int r[],int n,int k) { int low,high,mid,found; low=1; high=n; found=0; while((low<=high)&&(found==0)) { mid=(low+high)/2; if(k>r[mid]) low=mid+1; else if(k==r[mid]) found=1; else high