From 12be876131ad76d0fb8e7d0fbff586ea1a0a693e Mon Sep 17 00:00:00 2001 From: maedhros Date: Tue, 12 Jun 2007 22:13:49 +0000 Subject: [PATCH] (svn r10122) -Codechange: Add a CountBitsSet function and use it to replace some less efficient loops. --- src/economy.cpp | 14 +++----------- src/functions.h | 4 +++- src/misc.cpp | 15 +++++++++++++++ src/roadveh_cmd.cpp | 9 +-------- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/economy.cpp b/src/economy.cpp index 64bcbe832e..967373c734 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -67,10 +67,7 @@ int64 CalculateCompanyValue(const Player* p) uint num = 0; FOR_ALL_STATIONS(st) { - if (st->owner == owner) { - uint facil = st->facilities; - do num += (facil&1); while (facil >>= 1); - } + if (st->owner == owner) num += CountBitsSet(st->facilities); } value = num * _price.station_value * 25; @@ -144,10 +141,7 @@ int UpdateCompanyRatingAndValue(Player *p, bool update) const Station* st; FOR_ALL_STATIONS(st) { - if (st->owner == owner) { - int facil = st->facilities; - do num += facil&1; while (facil>>=1); - } + if (st->owner == owner) num += CountBitsSet(st->facilities); } _score_part[owner][SCORE_STATIONS] = num; } @@ -196,9 +190,7 @@ int UpdateCompanyRatingAndValue(Player *p, bool update) /* Generate score for variety of cargo */ { - uint cargo = p->cargo_types; - uint num = 0; - do num += cargo&1; while (cargo>>=1); + uint num = CountBitsSet(p->cargo_types); _score_part[owner][SCORE_CARGO] = num; if (update) p->cargo_types = 0; } diff --git a/src/functions.h b/src/functions.h index 12cf9deb86..cc885917e2 100644 --- a/src/functions.h +++ b/src/functions.h @@ -147,9 +147,11 @@ Town *ClosestTownFromTile(TileIndex tile, uint threshold); void ChangeTownRating(Town *t, int add, int max); uint GetTownRadiusGroup(const Town* t, TileIndex tile); -int FindFirstBit(uint32 x); void ShowHighscoreTable(int difficulty, int8 rank); +int FindFirstBit(uint32 x); +int CountBitsSet(uint32 value); + void AfterLoadTown(); void UpdatePatches(); void AskExitGame(); diff --git a/src/misc.cpp b/src/misc.cpp index 2dd2750d00..d143980c49 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -270,6 +270,21 @@ int FindFirstBit(uint32 value) return i; } +int CountBitsSet(uint32 value) +{ + int num; + + /* This loop is only called once for every bit set by clearing the lowest + * bit in each loop. The number of bits is therefore equal to the number of + * times the loop was called. It was found at the following website: + * http://graphics.stanford.edu/~seander/bithacks.html */ + + for (num = 0; value != 0; num++) { + value &= value - 1; + } + + return num; +} static void Save_NAME() { diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index b66483e70b..5c5e4023b1 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -1085,15 +1085,8 @@ static void RoadZPosAffectSpeed(Vehicle *v, byte old_z) static int PickRandomBit(uint bits) { - uint num = 0; - uint b = bits; uint i; - - do { - if (b & 1) num++; - } while (b >>= 1); - - num = RandomRange(num); + uint num = RandomRange(CountBitsSet(bits)); for (i = 0; !(bits & 1) || (int)--num >= 0; bits >>= 1, i++) {} return i;