![](/img/trans.png)
[英]How to order set<pair<unsigned int, double> > by the second value of pair?
[英]How to use a bitflag on an unsigned int in order to store an additional bool value in it
我在游戲中使用代表一組飛機的無符號整數。 每架飛機都有兩種狀態,飛行和接地。 我想將這個狀態與飛機號碼一起存儲。 實現這一目標的“最佳”方式是什么? 我可以使用std :: maps與飛機及其狀態,但這似乎有點過分和緩慢。 可以用位標志來完成嗎? 測試的分配和測試應該很快。
偽代碼:
unsigned int Boing = 777;
if( Boing is flying)
set some bit;
is Boing flying? (how to check for the current state)
任何關於簡單快速技術的暗示都值得贊賞!
最快和最干凈的方法可能是避免使用位域,只需定義一個結構:
struct Plane
{
bool isFlying;
unsigned int number;
}
...
std::vector<Plane> planes;
Plane p;
p.isFlying = true;
p.number = 777;
planes.push_back(p);
此方法將使用更多的內存,而不是嘗試將標志塞入同一個單詞,但獲取/設置字段所需的工作量較少。 除非你受到內存限制,否則我強烈建議避免嘗試緊緊包裝所有內容。
您甚至可以考慮使用enum
而不是bool
來表示州。
一種簡單的方法是,如果不飛行,只需將數字設為負數。
struct Stuff
{
unsigned int Boing: 31;
unsigned int isFlying: 1;
};
.
.
.
Stuff myStuff;
myStuff.Boing = 777;
myStuff.isFlying = false;
假設您從未使用unsigned int中可用的全部值(合理的可能性,但絕對不確定),您可以將范圍限制為比包含無符號的位少一位,然后使用最高位來存儲“飛行”狀態。 在這種情況下,您可以執行以下操作:
// This theoretically isn't required to work, but will for most reasonable machines.
unsigned flying_bit = 1 << (CHAR_BITS * sizeof(unsigned));
void take_off(unsigned &plane) {
plane |= flying_bit;
}
void land(unsigned &plane) {
plane &= flying_bit;
}
bool is_flying(unsigned const &plane) {
return plane & flying_bit != 0;
}
另一種可能性是使用實際的位域:
struct plane {
uint32_t model: 31;
uint32_t flying: 1;
};
在這種情況下,您只需直接指定值,例如:
plane myplane = {777, 0};
myplane.flying = 1; // take off
myplane.flying = 0; // land
為什么不簽署你的整數? 正值是飛行,負值不是,零是無效的。
使用結構或類來組合信息“數字”和“狀態”,以及您想要的任何平面。 如果對int使用位操作(這是可能的,只是不可取),更改狀態將改變實際的平面數。
假設你的unsigned int有32位:
#define SET_FLYING(x) (x) |= (1<<31)
#define SET_GROUNDED(x) (x) &= ~(1<<31)
#define IS_FLYING(x) ((x) & (1<<31))
#define ID(x) ((x) & ~(1<<31))
如果你想要更加時尚的c ++,你可以把它們寫成內聯函數。 無論如何,我寫了更多來向你展示如何進行位操作,而不是將其實現為宏還是函數。
要使其適用於不同大小的int,您可以將31更改為:
instead of 31: ((sizeof(x)<<3)-1)
這基本上是sizeof(x)*8-1
PS如果有人想告訴我“不不!不要使用宏,這是C ++,使用我寫的這個過於復雜的東西”,省去你的呼吸。 只需給-1並繼續前進。
編輯 :我上面寫的是你的問題的答案:“如何使用符號位作為標志”。 如果你想以更好的方式做到這一點,但不擴展你的內存使用量(通過添加bool
),你總是可以寫這樣的東西:
struct airplane
{
unsigned int id: 31;
unsigned int is_flying: 1;
};
airplane Boing = {777, false};
然后,分配和讀取id
或is_flying
執行位操作,但它們由編譯器處理。
您可以將狀態和平面編號打包在unsigned int中 。 假設unsigned int在您的平台上是32位
unsigned int myplane;
int planenumber = (myplane & 0xffff ) //can be the plane number
int booleanstate = ((myplane >> 16) & 0xffff) //can be the boolean state
使用bitset索引作為平面編號的bitset怎么樣? 如果您不需要更多狀態,那么您就完成了。 如果你需要,你也可以使用每個狀態(例如崩潰,修復需要一個單獨的位向量,所以你只需要為你實際需要的每個平面狀態使用一個位。
但我懷疑,如果你處理游戲圖形,物理速度會成為你的主要考慮因素,與飛機狀態下的操作相比,物理會占用大部分CPU時間。
#include <iostream>
#include <boost/dynamic_bitset.hpp>
using namespace boost;
class State
{
public:
State(int nPlanes):_States(dynamic_bitset<>(nPlanes))
{
}
void SetState(int nPlane, bool bFly)
{
_States[nPlane] = bFly;
}
void Dump()
{
for (boost::dynamic_bitset<>::size_type i = 0; i < _States.size(); ++i)
std::cout << _States[i];
}
private:
dynamic_bitset<> _States;
};
int _tmain(int argc, _TCHAR* argv[])
{
State planes(500);
planes.SetState(0, true);
planes.SetState(5,true);
planes.Dump();
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.