我无法通过提取部分字符串来尝试对数字进行签名扩展。当它是负数时会出现问题,它会将数字包装到正数。 这是我的代码:
// printf("add1 \n");
unsigned short r1 = (instruction>>6)&7;
signed short amount = (instruction& 31); //right here! i am trying to get the last 5 bits and store it in a register but i can't figure out how to make it negative if it is negative
// printf("\namount is %d \n", amount);
unsigned short dest = (instruction>>9)&7;
state->regs[dest] = state->regs[r1]+amount;
setCC(state,state->regs[r1]+amount);
答案 0 :(得分:2)
使用位域:
union {
int a;
struct {
int a:5;
int b:3;
unsigned int c:20;
} b;
} u = 0xdeadbeef;
int b = u.b.b; // should sign extend the 3-bit bitfield starting from bit 5
答案 1 :(得分:1)
对于位模式,使用十六进制常量而不是十进制通常更容易。
signed short amount = (instruction & 0x1F);
然后对符号进行符号扩展,检查符号位(假设此处的符号位是5个提取位中最左边的)。 如果已设置,则执行二进制反转并添加1. 取5位值的2的补码(反转并加1),然后取全宽结果的2的补码(反转并添加1)。
if (amount & 0x10)
amount = ~(amount^0x1F + 1) + 1;
例如
5-bit "bitfield"
X XXXX
0000 0000 0001 1111
0000 0000 0000 0000 invert x ^ 0x1F (= 1 1111)
0000 0000 0000 0001 add 1
1111 1111 1111 1110 invert ~
1111 1111 1111 1111 add 1
0000 0000 0001 0000
0000 0000 0000 1111 invert x ^ 0x1F (= 1 1111)
0000 0000 0001 0000 add 1
1111 1111 1110 1111 invert ~
1111 1111 1111 0000 add 1
糟糕!更简单:
-(x^0x1F + 1) Assuming the machine operates with 2's-complement
0000 0000 0001 0110
0000 0000 0000 1001 invert
0000 0000 0000 1010 add 1 (yielding the full-width absolute value)
1111 1111 1111 0101 negate
答案 2 :(得分:1)
以下是如何签名扩展5位二进制补码值而无需测试:
int amount = (instruction & 31) - ((instruction & 16) << 1);
更一般地说,字段宽度为n
,非零且小于int
中的位数,您可以写:
int amount = (instruction & ~(~1U << (n - 1) << 1)) -
((instruction & (1U << (n - 1)) << 1);
答案 3 :(得分:0)
您可以检查符号位并相应地修正结果:
int width_of_field = 5;
signed short amount = (instruction& 31);
if (amount & (1 << width_of_field >> 1)) // look at the sign bit
{
amount -= 1 << width_of_field; // fix the result
}
或者,使用左移然后右移:
width_of_field = 5;
signed short amount = (instruction& 31);
// It is possible to omit the "& 31", because of the left shift below
amount <<= 16 - width_of_field;
amount >>= 16 - width_of_field;
注意:必须使用两个语句来避免促销对int
(可能有32位)的影响。
答案 4 :(得分:0)
摘自Hacker's Delight 2-6。假设必须对5位数据进行符号扩展(符号位的值为16)。
最佳情况:如果高位全为零:
<ns0:MainNode xmlns:ns0="http://test/system">
<ParentTag>
<tagRequest>
<Data1>FirstName</Data1>
<Data2>LastName</Data2>
<Value1>50</Value1>
<BooleanValue1>false</BooleanValue1>
<Address>
<StreetName>0000000</StreetName>
<StreetNo>00000000000000</StreetNo>
</Address>
</tagRequest>
</ParentTag>
</ns0:MainNode>
下一个最佳情况(与OP的 <?xml version='1.0' ?>
<xsl:stylesheet version="1.0" xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:template match="/">
<ns0:MainNode xmlns:ns0="http://test/system">
<xsl:copy-of select="soapenv:Envelope/soapenv:Body/*" />
</ns0:MainNode>
</xsl:template>
<xsl:template match="Street-No">
<xsl:element name= "StreetNo">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
一样):如果高位包含必须丢弃的数据:
(i ^ 16) - 16