Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将多个布尔值放入无符号字符中?_C++_Bitwise Operators - Fatal编程技术网

C++ 将多个布尔值放入无符号字符中?

C++ 将多个布尔值放入无符号字符中?,c++,bitwise-operators,C++,Bitwise Operators,目前我正在开发一个NES模拟器,我正在开发CPU内核。我已经在互联网上搜索过了,但是我找不到合适的关键词来找到我问题的答案,所以我想我应该在这里问一下。我有七个布尔值作为我的处理器状态标志。我正在处理的当前操作码希望我将处理器状态标志推送到堆栈中。我的堆栈是无符号字符数据类型。我以为我能像这样把布尔人打在一起: bool C, Z, I, D, B, V, N; unsigned char example; example = {C, Z, I, D, B, V, N, 0}; 这不起作用,

目前我正在开发一个NES模拟器,我正在开发CPU内核。我已经在互联网上搜索过了,但是我找不到合适的关键词来找到我问题的答案,所以我想我应该在这里问一下。我有七个布尔值作为我的处理器状态标志。我正在处理的当前操作码希望我将处理器状态标志推送到堆栈中。我的堆栈是无符号字符数据类型。我以为我能像这样把布尔人打在一起:

bool C, Z, I, D, B, V, N;
unsigned char example;

example = {C, Z, I, D, B, V, N, 0};

这不起作用,那么如何将所有布尔处理器状态标志放入无符号字符数据类型中,以便将标志推送到堆栈中?

试试
std::bitset
。我找不到使用初始值设定项列表来构造它的方法,但是您可以始终使用
运算符[]
set()
来设置每个位,并使用
to_ulong()
将其转换为一个数字(然后您可以轻松地将无符号长字符转换为无符号字符)

#包括
#包括
使用名称空间std;
int main()
{
位集寄存器;
bool C=true,Z=false,I=false,D=false,B=true,V=true,N=false;
reg[6]=C;
reg[5]=Z;
reg[4]=I;
reg[3]=D;
reg[2]=B;
reg[1]=V;
reg[0]=N;
unsigned char example=static_cast(reg.to_ulong());
printf(“0x%x\n”,示例);
返回0;
}

试试
std::bitset
。我找不到使用初始值设定项列表来构造它的方法,但是您可以始终使用
运算符[]
set()
来设置每个位,并使用
to_ulong()
将其转换为一个数字(然后您可以轻松地将无符号长字符转换为无符号字符)

#包括
#包括
使用名称空间std;
int main()
{
位集寄存器;
bool C=true,Z=false,I=false,D=false,B=true,V=true,N=false;
reg[6]=C;
reg[5]=Z;
reg[4]=I;
reg[3]=D;
reg[2]=B;
reg[1]=V;
reg[0]=N;
unsigned char example=static_cast(reg.to_ulong());
printf(“0x%x\n”,示例);
返回0;
}
试试这个:

bool C, Z, I, D, B, V, N;
unsigned char example = 0;

if(C)
   example |= (1 << 7)
if(Z)
   example |= (1 << 6)
if(I)
   example |= (1 << 5)
if(D)
   example |= (1 << 4)
if(B)
   example |= (1 << 3)
if(V)
   example |= (1 << 2)
if(N)
   example |= (1 << 1)
boolc,Z,I,D,B,V,N;
无符号字符示例=0;
如果(C)
示例|=(1试试这个:

bool C, Z, I, D, B, V, N;
unsigned char example = 0;

if(C)
   example |= (1 << 7)
if(Z)
   example |= (1 << 6)
if(I)
   example |= (1 << 5)
if(D)
   example |= (1 << 4)
if(B)
   example |= (1 << 3)
if(V)
   example |= (1 << 2)
if(N)
   example |= (1 << 1)
boolc,Z,I,D,B,V,N;
无符号字符示例=0;
如果(C)

示例|=(1这应该是您正在寻找的:

bool C, Z, I, D, B, V, N;
unsigned char example = 0;
const unsigned char mask = 0x01;

if(N)
   example |= mask << 1;
if(V)
   example |= mask << 2;
//...   
if(C)
   example |= mask << 7;
boolc,Z,I,D,B,V,N;
无符号字符示例=0;
常量无符号字符掩码=0x01;
如果(N)

示例|=mask这应该是您正在寻找的:

bool C, Z, I, D, B, V, N;
unsigned char example = 0;
const unsigned char mask = 0x01;

if(N)
   example |= mask << 1;
if(V)
   example |= mask << 2;
//...   
if(C)
   example |= mask << 7;
boolc,Z,I,D,B,V,N;
无符号字符示例=0;
常量无符号字符掩码=0x01;
如果(N)

示例|=mask在模拟器中放置该值可能有点重,但为什么不将每个布尔值转换为字符中的一位,然后在需要将字符从堆栈中取出时对其进行解码呢

unsigned char encodeBits(bool bools[8]) {
    unsigned char retval = 0;
    for(int i = 0; i < 8; i++) {
        retval += (bools[i] ? 1 : 0);
        retval = (i < 7 ? retval << 1 : retval);
    }

    return retval;
}
无符号字符编码位(bool bools[8]){
无符号字符retval=0;
对于(int i=0;i<8;i++){
retval+=(bools[i]?1:0);
retval=(i<7?retval>1:输入);
}
}
此代码应比较字符的第一位,然后将其移位等

这可以在没有阵列的情况下完成,但为了简单起见,我使用了阵列


编辑:一个工作示例:

在模拟器中输入这可能有点重,但是为什么不将每个布尔值转换为字符中的一位,然后在需要将字符从堆栈中取出时对其进行解码呢

unsigned char encodeBits(bool bools[8]) {
    unsigned char retval = 0;
    for(int i = 0; i < 8; i++) {
        retval += (bools[i] ? 1 : 0);
        retval = (i < 7 ? retval << 1 : retval);
    }

    return retval;
}
无符号字符编码位(bool bools[8]){
无符号字符retval=0;
对于(int i=0;i<8;i++){
retval+=(bools[i]?1:0);
retval=(i<7?retval>1:输入);
}
}
此代码应比较字符的第一位,然后将其移位等

这可以在没有阵列的情况下完成,但为了简单起见,我使用了阵列


编辑:一个工作示例:

假设
int status
是您的CPU状态寄存器。 您可以创建如下定义:

#define CPU_REG_STATUS_C 0x00000040
#define CPU_REG_STATUS_Z 0x00000020
#define CPU_REG_STATUS_I 0x00000010
#define CPU_REG_STATUS_D 0x00000008
#define CPU_REG_STATUS_B 0x00000004
#define CPU_REG_STATUS_V 0x00000002
#define CPU_REG_STATUS_N 0x00000001
然后通过使用位二进制运算符和独立地设置/取消设置标志|

示例1:设置零标志

status |= CPU_REG_STATUS_Z;
示例2:检查零标志的值:

if(status & CPU_REG_STATUS_Z)
{
   //zero flag is set
}
else
{
   //zero flag is unset
}
然而,有大量的CPU核心源代码,特别是6502 CPU(Commodore C64、Nintendo NES和许多其他产品),因此您只需对控制台进行仿真即可


假设
int status
是您的CPU状态寄存器。 您可以创建如下定义:

#define CPU_REG_STATUS_C 0x00000040
#define CPU_REG_STATUS_Z 0x00000020
#define CPU_REG_STATUS_I 0x00000010
#define CPU_REG_STATUS_D 0x00000008
#define CPU_REG_STATUS_B 0x00000004
#define CPU_REG_STATUS_V 0x00000002
#define CPU_REG_STATUS_N 0x00000001
然后通过使用位二进制运算符和独立地设置/取消设置标志|

示例1:设置零标志

status |= CPU_REG_STATUS_Z;
示例2:检查零标志的值:

if(status & CPU_REG_STATUS_Z)
{
   //zero flag is set
}
else
{
   //zero flag is unset
}
然而,有大量的CPU核心源代码,特别是6502 CPU(Commodore C64、Nintendo NES和许多其他产品),因此您只需对控制台进行仿真即可

这是因为每个常量中只设置了一位。若要确定是否设置了标志,请使用
(flags&FLAGNAME)
(flags&C)
来确定是否设置了标志。小心不要将我使用的按位AND(&)与布尔/逻辑AND(&&)混淆。和运算符将无法代替和运算符。若要设置标志,请使用
(标志|=标志名)
若要取消设置,请使用
标志&=~FLAGNAME;
。将常量调整为正确的顺序,以便NES指令可以正确检查标志。毕竟,如果它们的顺序不正确,可能会使用错误的标志值,这显然是一个问题

另外,不要忘记括号。按位运算符的优先级很低,因此表达式周围的括号是必不可少的

如果您不知道按位运算符,那么值得一读

编辑

为您提供了一套方便的宏:

#define FLAG_ISSET(x) (flags & (x))
#define FLAG_SET(x) (flags |= (x))
#define FLAG_CLEAR(x) (flags &= ~(x))

...
if (FLAG_ISSET(C))
  ...

FLAG_SET(V);
FLAG_CLEAR(Z);
这是因为每个常量中只设置了一位。要确定是否设置了标志,请使用
(flags&FLAGNAME)
类似
(fla