문제

I'm trying to convert an integer value to a content alignment. The integer can hold both a horizontal and a vertical alignment at the same time.

First I created an enum, which describes all possibilities (i have to use the values of android Gravity class: http://developer.android.com/reference/android/view/Gravity.html)

typedef enum{
    GravityHorizontalCenter         = 1,    // (0x00000001) 
    GravityLeft                     = 2,    // (0x00000002) 
    GravityRight                    = 5,    // (0x00000005) 
    GravityVerticalCenter           = 16,   // (0x00000010) 
    GravityTop                      = 48,   // (0x00000030) 
    GravityBottom                   = 80,   // (0x00000050) 
} GravityType;

So int alignment = GravityRight | GravityTop would be 53.

I want to check the alignment of my view-objects like this:

if ((textAlignment & GravityHorizontalCenter) == GravityHorizontalCenter){

    return NSTextAlignmentCenter;
}...

But there seems to be something missing, because for 53 the if statement textAlignment & GravityHorizontalCenter) == GravityHorizontalCenter returns True.

도움이 되었습니까?

해결책

You need masks for the the Vertical and Horizontal ranges.

typedef enum{
    GravityHorizontalCenter         = 1,    // (0x00000001) 
    GravityLeft                     = 2,    // (0x00000002) 
    GravityRight                    = 5,    // (0x00000005) 
    GravityHorizontalMask           = 7,    // (0x00000007) 
    GravityVerticalCenter           = 16,   // (0x00000010) 
    GravityTop                      = 48,   // (0x00000030) 
    GravityBottom                   = 80,   // (0x00000050) 
    GravityVerticalMask             = 112,  // (0x00000070) 
} GravityType;

Then you can do a test with:

(textAlignment & GravityHorizontalMask) == GravityHorizontalCenter

or

(textAlignment & GravityVerticalMask) == GravityTop

These values are only really suitable for direct comparison, since 5 (101 binary) and 1 (001 binary) overlap as bit masks. But since you are storing two values in the same number (the first 4 bits for the horizontal alignment, and the second 4 bits for the vertical alignment), you need a mask to isolate the range of bits that you want to compare.

Also, you should be aware that on Android the value of LEFT (the left gravity constant) is 3 and not 2. So if your enum really needs to be compatible with Android then your GravityLeft value is probably incorrect.

다른 팁

Because these values are not suited for being used as bit flags (masks).

& is not magic - it's just the bitwise AND operator. And if you bitwise AND a number with 1 then you compare the result to 1, that only checks if the least significant bit was set in the original number, i. e. if it was odd. Thus, (textAlignment & GravityHorizontalCenter) == GravityHorizontalCenter will yield true for any odd number.

If you want to use numbers as flags, you have to make them different powers of two, like this:

GravityHorizontalCenter         = 1,
GravityLeft                     = 2,
GravityRight                    = 4,
GravityVerticalCenter           = 8,
GravityTop                      = 16,
GravityBottom                   = 32,
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top