Reputation: 5327
I've taken over a project and it uses an enum to flag API calls.
It can filter them by OR'ing the enum values so a previous developer did some bitshifting.
typedef enum {
APICallTimeSeriesSearchTimeSeries = (1LL << 1),
APICallTimeSeriesGetTimeSeriesInfo = (1LL << 2),
APICallTimeSeriesGetSeriesInfo = (1LL << 3),
....
APICallFavouritesAddNewsFavourite = (1LL << 79),
APICallFavouritesRemoveNewsFavourite = (1LL << 80),
APICallFavouritesGetAllFavourites = (1LL << 81)
} APICallType;
Then we can do things like
filter(APICallTimeSeriesGetTimeSeriesInfo | APICallTimeSeriesGetSeriesInfo | APICallTimeSeriesGetSeriesData);
But recently I notice similar enums mapped to the same value. I dumped the whole enum list like so
NSLog(@"%d",APICallTimeSeriesSearchTimeSeries);
NSLog(@"%d",APICallTimeSeriesGetTimeSeriesInfo);
NSLog(@"%d",APICallTimeSeriesGetSeriesInfo);
NSLog(@"%d",APICallTimeSeriesGetSeriesData);
NSLog(@"%d",APICallFleetSearchVessels);
NSLog(@"%d",APICallFleetGetVesselInfo);
etc.
And we can see the bitshifting in action
2
4
8
16
32
64
128
256
512
1024
2048
4096
8192
16384
32768
65536
131072
262144
524288
1048576
2097152
4194304
8388608
16777216
33554432
67108864
134217728
268435456
536870912
1073741824
2147483648
4294967296
8589934592
17179869184
34359738368
68719476736
The problem is after (1LL << 63) the same values are generated
1152921504606846976 APICallFavouritesAddMarketFavourite = (1LL << 60)
2305843009213693952 APICallFavouritesRemoveMarketFavourite = (1LL << 61)
4611686018427387904 APICallFavouritesGetFutureFavourites = (1LL << 62)
-9223372036854775808 APICallFavouritesAddFutureFavourite = (1LL << 63)
-9223372036854775808 APICallFavouritesRemoveFutureFavourite = (1LL << 64)
-9223372036854775808 APICallFavouritesRemoveVesselFavourite = (1LL << 65)
etc same value(-9223372036854775808) repeats for all new enums
From this thread Types in objective-c on iPhone
its because -9223372036854775808 is LLONG_MIN
NSLog(@"LLONG_MIN: %lli", LLONG_MIN); // signed long long int
I noticed theres a higher value
NSLog(@"LLONG_MAX: %lli", LLONG_MAX);
NSLog(@"ULLONG_MAX: %llu", ULLONG_MAX); // unsigned long long int
LLONG_MIN: -9223372036854775808
LLONG_MAX: 9223372036854775807
ULLONG_MAX: 18446744073709551615
but cant find ULLONG_MIN
How do we fix this?
I tried changing the primitive storage from 1LL to 1ULL but no effect.
FROM:
typedef enum {
APICallTimeSeriesSearchTimeSeries = (1LL << 1),
APICallTimeSeriesGetTimeSeriesInfo = (1LL << 2),
APICallTimeSeriesGetSeriesInfo = (1LL << 3),
...
TO:
typedef enum {
APICallTimeSeriesSearchTimeSeries = (1ULL << 1),
APICallTimeSeriesGetTimeSeriesInfo = (1ULL << 2),
APICallTimeSeriesGetSeriesInfo = (1ULL << 3),
...
cheers
Upvotes: 0
Views: 913
Reputation: 5327
I chose to split the APICallType into another enum. It was that or rewire a 3 year old projects and have to test every API call.
APICallTimeSeriesSearchTimeSeries = (1LL << 1),
APICallTimeSeriesGetTimeSeriesInfo = (1LL << 2),
APICallTimeSeriesGetSeriesInfo = (1LL << 3),
....
APICallFavouritesAddNewsFavourite = (1LL << 79),
APICallFavouritesRemoveNewsFavourite = (1LL << 80),
APICallFavouritesGetAllFavourites = (1LL << 81)
} APICallType;
CHANGED TO
typedef enum {
APICallTimeSeriesSearchTimeSeries = (1LL << 1),
APICallTimeSeriesGetTimeSeriesInfo = (1LL << 2),
APICallTimeSeriesGetSeriesInfo = (1LL << 3),
APICallTimeSeriesGetSeriesData = (1LL << 4),
APICallFleetSearchVessels = (1LL << 5),
APICallFleetGetVesselInfo = (1LL << 6),
APICallNewsGetNewsItems = (1LL << 7),
APICallNewsGetPublicationItems = (1LL << 8),
APICallPodcastGetPodcastItems = (1LL << 9),
APICallUserLoginAuthenticateUser = (1LL << 10),
APICallFFASearchFFARoutes = (1LL << 11),
APICallFFAGetRouteData = (1LL << 12),
APICallOwnerSearchOwners = (1LL << 13),
APICallOwnerGetOwnerFleet = (1LL << 14),
APICallIndicesSearchIndices = (1LL << 15),
APICallIndicesGetIndicesData = (1LL << 16),
APICallEquitiesGetEquitiesData = (1LL << 17),
APICallEquitiesGetEquityPreviews = (1LL << 18),
APICallEquitiesSearchBrokingStocks = (1LL << 19),
APICallEquitiesSearchIndices = (1LL << 20),
APICallEquitiesSearchCurrencies = (1LL << 21),
APICallEquitiesGetRelatedNewsItems = (1LL << 22),
APICallEquitiesGetCurrencyList = (1LL << 23),
APICallSandPVesselsSearch = (1LL << 24),
APICallSandPVesselSalesSearch = (1LL << 25),
APICallSandPGetCommercialData = (1LL << 26),
APICallSandPGetSimilarSales = (1LL << 27),
APICallSandPGetFullVesselDetails = (1LL << 28),
APICallSandPEnquiriesSearch = (1LL << 29),
APICallTimeSeriesGetCategories = (1LL << 30),
APICallTimeSeriesGetShipTypes = (1LL << 31),
APICallTimeSeriesGetDataTypes = (1LL << 32),
APICallTimeSeriesSearchTimeSeriesWithCategories = (1LL << 33),
APICallHomeGetComments = (1LL << 34),
APICallEquitiesGetRelatedNewsItemsWithIds = (1LL << 35),
APICallEquitiesSearchEquitiesBrokingStocks = (1LL << 36),
APICallTimeSeriesGetFutureShipTypes = (1LL << 37),
APICallTimeSeriesGetFutureDataTypes = (1LL << 38),
APICallTimeSeriesGetOHLCData = (1LL << 39),
APICallTimeSeriesGetSeriesDataMaxPoints = (1LL << 40),
APICallTimeSeriesGetSeriesOHLCDataMaxPoints = (1LL << 41),
APICallClientSearchClients = (1LL << 42),
APICallClientGetClientListForBroker = (1LL << 43),
APICallClientSearchDivisionsAndDesks = (1LL << 44),
APICallClientGetDivisionsAndDesks = (1LL << 45),
APICallClientSaveEmployeeDetails = (1LL << 46),
APICallTimeSeriesSearchWithSeriesId = (1LL << 47),
APICallHomeGetCommentsCargo = (1LL << 48),
APICallHomeGetCommentsSandP = (1LL << 49),
APICallHomeGetCommentsTanker = (1LL << 50),
APICallClientGetSandPRoutes = (1LL << 51),
APICallClientGetSandP2ndHandValues = (1LL << 52),
APICallHomeGetCommentsSpecialised = (1LL << 53),
APICallClientGetSpecialised = (1LL << 54),
APICallClientGetGas = (1LL << 55),
APICallClientGetGasBunkerPrices = (1LL << 56),
APICallFFAGetAllWhiteboardSpreadTypes = (1LL << 57),
APICallFFAGetWhiteboardSpreadPricesForType = (1LL << 58),
APICallFavourites = (1LL << 59)
/*
APICallFavouritesGetMarketFavourites = (1LL << 59),
APICallFavouritesAddMarketFavourite = (1LL << 60),
APICallFavouritesRemoveMarketFavourite = (1LL << 61),
APICallFavouritesGetFutureFavourites = (1LL << 62),
//Enum bit shifted greater than 63 will have same value as MAX INT reached
//moved these to
APICallFavouritesAddFutureFavourite = (1LL << 63),
APICallFavouritesRemoveFutureFavourite = (1LL << 64),
APICallFavouritesGetVesselOwnerFavourites = (1LL << 65),
APICallFavouritesGetVesselFavourites = (1LL << 66),
APICallFavouritesAddVesselFavourite = (1LL << 67),
APICallFavouritesRemoveVesselFavourite = (1LL << 68),
APICallFavouritesGetOwnerFavourites = (1LL << 69),
APICallFavouritesAddOwnerFavourite = (1LL << 70),
APICallFavouritesRemoveOwnerFavourite = (1LL << 71),
APICallFavouritesGetShippingStockFavourites = (1LL << 72),
APICallFavouritesAddShippingStockFavourite = (1LL << 73),
APICallFavouritesRemoveShippingStockFavourite = (1LL << 74),
APICallFavouritesGetIndicieFavourites = (1LL << 75),
APICallFavouritesAddIndicieFavourite = (1LL << 76),
APICallFavouritesRemoveIndicieFavourite = (1LL << 77),
APICallFavouritesGetNewsFavourites = (1LL << 78),
APICallFavouritesAddNewsFavourite = (1LL << 79),
APICallFavouritesRemoveNewsFavourite = (1LL << 80),
APICallFavouritesGetAllFavourites = (1LL << 81)
*/
} APICallType;
AND ADDED APICallSubType
typedef enum {
/* for use with APICallType:APICallFavourites */
APICallFavouritesGetMarketFavourites = (1LL << 1),
APICallFavouritesAddMarketFavourite = (1LL << 2),
APICallFavouritesRemoveMarketFavourite = (1LL << 3),
APICallFavouritesGetFutureFavourites = (1LL << 4),
APICallFavouritesAddFutureFavourite = (1LL << 5),
APICallFavouritesRemoveFutureFavourite = (1LL << 6),
APICallFavouritesGetVesselOwnerFavourites = (1LL << 7),
APICallFavouritesGetVesselFavourites = (1LL << 8),
APICallFavouritesAddVesselFavourite = (1LL << 9),
APICallFavouritesRemoveVesselFavourite = (1LL << 10),
APICallFavouritesGetOwnerFavourites = (1LL << 11),
APICallFavouritesAddOwnerFavourite = (1LL << 12),
APICallFavouritesRemoveOwnerFavourite = (1LL << 13),
APICallFavouritesGetShippingStockFavourites = (1LL << 14),
APICallFavouritesAddShippingStockFavourite = (1LL << 15),
APICallFavouritesRemoveShippingStockFavourite = (1LL << 16),
APICallFavouritesGetIndicieFavourites = (1LL << 17),
APICallFavouritesAddIndicieFavourite = (1LL << 18),
APICallFavouritesRemoveIndicieFavourite = (1LL << 19),
APICallFavouritesGetNewsFavourites = (1LL << 20),
APICallFavouritesAddNewsFavourite = (1LL << 21),
APICallFavouritesRemoveNewsFavourite = (1LL << 22),
APICallFavouritesGetAllFavourites = (1LL << 23)
//do not go over (1LL << 63) - enum values start at MAX INT after that
} APICallSubType;
AND ANYWHERE I CHECKED the type I had to afterwards check the subtype
filter(APICallFavourites);
filterSubType(APICallFavouritesAddVesselFavourite |
APICallFavouritesRemoveVesselFavourite);
if (responseOfSubType(APICallFavouritesAddVesselFavourite))
{
NSLog(@"%s APICallFavouritesAddVesselFavourite response not handled", __PRETTY_FUNCTION__);
}
if (responseOfSubType(APICallFavouritesRemoveVesselFavourite))
{
NSLog(@"%s APICallFavouritesRemoveVesselFavourite response not handled", __PRETTY_FUNCTION__);
}
Upvotes: 0
Reputation: 1301
ULLONG_MIN is 0. ULLONG means unsigned long long, i.e. a positive value represented by 64 bits.
If you want positive and negative numbers you can only represent half of that set of values that you can represent by an unsigned type of the same bit width. That's the reason that the ULLONG_MAX is bigger.
Upvotes: 1