为什么位模式与 std::bitset 的使用不匹配
Why are the bit patterns not matching with the use of std::bitset
当我对我的 class 及其构造函数进行单元测试时,我注意到我的输出有些奇怪。
#include <bitset>
#include <cstdint>
#include <iostream>
#include <vector>
typedef std::uint8_t u8;
typedef std::uint16_t u16;
typedef std::uint32_t u32;
typedef std::uint64_t u64;
struct Reg8 {
std::bitset<8> bits;
u8 value;
Reg8() : value{0}, bits{value} {}
explicit Reg8( u8 val) : value{val}, bits{value} {}
explicit Reg8(u16 val) : value{static_cast<u8>(val)}, bits{value} {}
explicit Reg8(u32 val) : value{static_cast<u8>(val)}, bits{value} {}
explicit Reg8(u64 val) : value{static_cast<u8>(val)}, bits{value} {}
};
int main() {
u8 val8 = 24;
u16 val16 = 24;
u32 val32 = 24;
u64 val64 = 24;
Reg8 r8a(val8);
Reg8 r8b(val16);
Reg8 r8c(val32);
Reg8 r8d(val64);
std::cout << "Reg8(u8) r8a value = " << +r8a.value << '\n';
std::cout << "Reg8(u8) r8a bits = " << r8a.bits << "\n\n";
std::cout << "Reg8(u16) r8b value = " << +r8b.value << '\n';
std::cout << "Reg8(u16) r8b bits = " << r8b.bits << "\n\n";
std::cout << "Reg8(u32) r8c value = " << +r8c.value << '\n';
std::cout << "Reg8(u32) r8c bits = " << r8c.bits << "\n\n";
std::cout << "Reg8(u64) r8d value = " << +r8d.value << '\n';
std::cout << "Reg8(u64) r8d bits = " << r8d.bits << "\n\n";
std::bitset<8> bitsA{ val8 };
std::cout << "bits value = " << bitsA.to_ullong() << '\n';
std::cout << "bits binary = " << bitsA << "\n\n";
std::bitset<8> bitsB{ val16 };
std::cout << "bits value = " << bitsB.to_ullong() << '\n';
std::cout << "bits binary = " << bitsB << "\n\n";
std::bitset<8> bitsC{ val32 };
std::cout << "bits value = " << bitsC.to_ullong() << '\n';
std::cout << "bits binary = " << bitsC << "\n\n";
std::bitset<8> bitsD{ val64 };
std::cout << "bits value = " << bitsD.to_ullong() << '\n';
std::cout << "bits binary = " << bitsD << "\n\n";
return EXIT_SUCCESS;
}
这是我的输出来自一个小端机器和
Intel Quad Core Extreme 运行 Windows 7 x64 并使用
Visual Studio x64 调试模式下的 2017 CE,编译器语言选项设置为 c++ 最新草案标准。所有其他编译器标志 - 优化等 Visual Studio 的默认值。
Reg8(u8) r8a value = 24
Reg8(u8) r8a bits = 11001100
Reg8(u16) r8b value = 24
Reg8(u16) r8b bits = 11001100
Reg8(u32) r8c value = 24
Reg8(u32) r8c bits = 11001100
Reg8(u64) r8d value = 24
Reg8(u64) r8d bits = 11001100
bits value = 24
bits binary = 00011000
bits value = 24
bits binary = 00011000
bits value = 24
bits binary = 00011000
bits value = 24
bits binary = 00011000
那么为什么 class 结构中的位模式与 main 中声明的位模式不匹配?
我使用相同的变量类型和值来初始化 main 中的位集以及 class 中的位集,但它们的位模式不匹配。 class里面的都一样,class外面的都一样。
我期望看到的和我想要的值应该是在 main 中看到的值。当我查看输出的下半部分时,main 中的这些 bitset 变量的值为 24
并且它们的位模式匹配 24 的 8 位。
0001 1000 = 24
然而,存储在我的 class 中位集中的位模式不匹配,但包含适当的值。存储在我的 class 中的位集具有位模式
1100 1100 ... doesn't = 24 in binary
这是怎么回事?
请记住,成员初始化列表按声明顺序进行初始化。意思是:
struct Reg8 {
std::bitset<8> bits; // <- first to be initialized in mem-init-list
u8 value; // <- second
};
并以此构造函数为例:
explicit Reg8(u16 val) : value{static_cast<u8>(val)}, bits{value} {}
初始化列表的顺序无关紧要。 bits
在声明中出现在 value
之前,因此 bits
将首先被初始化。它将被初始化为 value
,它仍未初始化,因为 value{static_cast<u8>(val)}
在 bits
.
初始化之后出现
要解决此问题,请交换声明:
struct Reg8 {
u8 value;
std::bitset<8> bits;
};
旁注:您的代码中缺少 stdint
包含。
当我对我的 class 及其构造函数进行单元测试时,我注意到我的输出有些奇怪。
#include <bitset>
#include <cstdint>
#include <iostream>
#include <vector>
typedef std::uint8_t u8;
typedef std::uint16_t u16;
typedef std::uint32_t u32;
typedef std::uint64_t u64;
struct Reg8 {
std::bitset<8> bits;
u8 value;
Reg8() : value{0}, bits{value} {}
explicit Reg8( u8 val) : value{val}, bits{value} {}
explicit Reg8(u16 val) : value{static_cast<u8>(val)}, bits{value} {}
explicit Reg8(u32 val) : value{static_cast<u8>(val)}, bits{value} {}
explicit Reg8(u64 val) : value{static_cast<u8>(val)}, bits{value} {}
};
int main() {
u8 val8 = 24;
u16 val16 = 24;
u32 val32 = 24;
u64 val64 = 24;
Reg8 r8a(val8);
Reg8 r8b(val16);
Reg8 r8c(val32);
Reg8 r8d(val64);
std::cout << "Reg8(u8) r8a value = " << +r8a.value << '\n';
std::cout << "Reg8(u8) r8a bits = " << r8a.bits << "\n\n";
std::cout << "Reg8(u16) r8b value = " << +r8b.value << '\n';
std::cout << "Reg8(u16) r8b bits = " << r8b.bits << "\n\n";
std::cout << "Reg8(u32) r8c value = " << +r8c.value << '\n';
std::cout << "Reg8(u32) r8c bits = " << r8c.bits << "\n\n";
std::cout << "Reg8(u64) r8d value = " << +r8d.value << '\n';
std::cout << "Reg8(u64) r8d bits = " << r8d.bits << "\n\n";
std::bitset<8> bitsA{ val8 };
std::cout << "bits value = " << bitsA.to_ullong() << '\n';
std::cout << "bits binary = " << bitsA << "\n\n";
std::bitset<8> bitsB{ val16 };
std::cout << "bits value = " << bitsB.to_ullong() << '\n';
std::cout << "bits binary = " << bitsB << "\n\n";
std::bitset<8> bitsC{ val32 };
std::cout << "bits value = " << bitsC.to_ullong() << '\n';
std::cout << "bits binary = " << bitsC << "\n\n";
std::bitset<8> bitsD{ val64 };
std::cout << "bits value = " << bitsD.to_ullong() << '\n';
std::cout << "bits binary = " << bitsD << "\n\n";
return EXIT_SUCCESS;
}
这是我的输出来自一个小端机器和 Intel Quad Core Extreme 运行 Windows 7 x64 并使用 Visual Studio x64 调试模式下的 2017 CE,编译器语言选项设置为 c++ 最新草案标准。所有其他编译器标志 - 优化等 Visual Studio 的默认值。
Reg8(u8) r8a value = 24
Reg8(u8) r8a bits = 11001100
Reg8(u16) r8b value = 24
Reg8(u16) r8b bits = 11001100
Reg8(u32) r8c value = 24
Reg8(u32) r8c bits = 11001100
Reg8(u64) r8d value = 24
Reg8(u64) r8d bits = 11001100
bits value = 24
bits binary = 00011000
bits value = 24
bits binary = 00011000
bits value = 24
bits binary = 00011000
bits value = 24
bits binary = 00011000
那么为什么 class 结构中的位模式与 main 中声明的位模式不匹配?
我使用相同的变量类型和值来初始化 main 中的位集以及 class 中的位集,但它们的位模式不匹配。 class里面的都一样,class外面的都一样。
我期望看到的和我想要的值应该是在 main 中看到的值。当我查看输出的下半部分时,main 中的这些 bitset 变量的值为 24 并且它们的位模式匹配 24 的 8 位。
0001 1000 = 24
然而,存储在我的 class 中位集中的位模式不匹配,但包含适当的值。存储在我的 class 中的位集具有位模式
1100 1100 ... doesn't = 24 in binary
这是怎么回事?
请记住,成员初始化列表按声明顺序进行初始化。意思是:
struct Reg8 {
std::bitset<8> bits; // <- first to be initialized in mem-init-list
u8 value; // <- second
};
并以此构造函数为例:
explicit Reg8(u16 val) : value{static_cast<u8>(val)}, bits{value} {}
初始化列表的顺序无关紧要。 bits
在声明中出现在 value
之前,因此 bits
将首先被初始化。它将被初始化为 value
,它仍未初始化,因为 value{static_cast<u8>(val)}
在 bits
.
要解决此问题,请交换声明:
struct Reg8 {
u8 value;
std::bitset<8> bits;
};
旁注:您的代码中缺少 stdint
包含。