5
$\begingroup$

I apologize but I'm not sure what you would even call this problem. I have some data that provide a numeric code for race as follows:

hispanic(1) + american_indian_or_alaska_native(2) + asian(4) + black_or_african_american(8) + native_hawaiian_or_other_pacific_islander(16) + white(32)

So for example, a 5 represents a person who identifies as Asian and Hispanic (4 + 1), and a 25 represents a person who identifies as Pacific Islander, Black, and Hispanic (16 + 8 + 1).

I am trying to write a program that will retrieve what races are present from the given number. I figure there must be an equation that can determine the combination without detailing every unique combination, but I might be wrong! I tried to think about using modulo but I didn't get very far.

Thanks, and if you have suggestions for tags, please comment as I'm not sure where this fits into mathematics.

*edit Thanks everyone! This really helped me to think about the problem and generate an efficient solution. Answering my question didn't depend on using SAS but here is the SAS code I ended up using, which I think shows intuitively how to solve the problem:

data want; 
    set have; 

/* convert decimal to 6-place binary */
    eth_bin = put(ethnicity, binary6.);  

/* if 1st digit is 1 then race is present, and so on*/ 
    if substr(eth_bin, 1, 1) = 1 then white = "Yes"; 
    if substr(eth_bin, 2, 1) = 1 then pacific_islander = "Yes"; 
    if substr(eth_bin, 3, 1) = 1 then black = "Yes"; 
    if substr(eth_bin, 4, 1) = 1 then asian = "Yes"; 
    if substr(eth_bin, 5, 1) = 1 then american_indian = "Yes"; 
    if substr(eth_bin, 6, 1) = 1 then hispanic = "Yes"; 
run; 
$\endgroup$
7
  • 5
    $\begingroup$ It's simple: It's a binary number. Look to the bit for the race. $\endgroup$ Nov 23, 2015 at 16:02
  • 2
    $\begingroup$ Thanks, obviously if I knew how to do that I wouldn't have posted the question. Can you elaborate? $\endgroup$ Nov 23, 2015 at 16:02
  • 1
    $\begingroup$ Your numbers are all powers of $2$. Given a number $n$, subtract the largest power of $2$ possible. Repeat until you reach $0$. The numbers you have subtracted are the numbers you are looking for. $\endgroup$
    – Servaes
    Nov 23, 2015 at 16:04
  • 6
    $\begingroup$ If you're going to use the answer for implementing on a computer, you should look into the bitwise operators of your favorite programming language. In particular, checking whether, for example (4 AND x) is nonzero is a much quicker way to check whether the person described by x is Asian than doing arithmetic -- and more readable too, once you get used to the idiom. (Such operators exist in R and SAS, for example). $\endgroup$ Nov 23, 2015 at 16:08
  • $\begingroup$ Thank you! So many good answers and I'm learning a lot! (I know the question is kind of simple but as I expected it's informative and fun to think about) $\endgroup$ Nov 23, 2015 at 16:15

7 Answers 7

9
$\begingroup$

Notice that the numbers $1, 2, 4, 8, 16, 32$ are all perfect powers of $2$. This means that from any sum of them, the individual components can always be retrieved because there is a unique way to express a number as a binary number. One way to retrieve the racial info is keep dividing by $2$ and getting the remainder. Every remainder of $1$ indicates a certain race (depending on the stage of division). If the remainder is $0$, that race is not present. To elaborate, roughly you follow this algorithm:

  1. Let $n$ be your number with the racial info.
  2. While $n$ is non-zero, re-assign $n$ to $\lfloor \frac{n}{2} \rfloor$ and make a note of the remainder. If the remainder is $1$, then that race is present, where the race starts at Hispanic and so on.
  3. When $n=0$ you are finished, there are no more races.

Update: Henning Makholm's suggestions to use bitwise operators is in fact a more elegant solution, programmatically, but may be harder to grasp intuitively.

$\endgroup$
3
  • $\begingroup$ Thanks! This was intuitive and definitely answered my question. I discovered that SAS (the program I'm using for this particular problem) has a format that converts decimal to binary, so it's straightforward from there. I wonder if you have a sense what a program that converts a decimal number to binary would look like? I will keep thinking about it too. $\endgroup$ Nov 23, 2015 at 16:36
  • 1
    $\begingroup$ No prob! I'm pretty sure the number will be stored as binary. I'd say the SAS binary format is just for printing the number. When you use bitwise operators, you don't need to "convert" the number to binary. You just operate on it as if it was a binary number. E.g. the number 27 to us is seen by the machine as 11011. So e.g. when you write (27 AND 16) you should get 1. $\endgroup$ Nov 23, 2015 at 16:43
  • 1
    $\begingroup$ To elaborate on Henning's comment, you basically do 5 tests on your number. if (number AND 1) then Hispanic=true else Hispanic=false etc. all the way up to if (number AND 32) then white=true else white=false. *I'm not familar with SAS syntax so I hope you can get it from that. $\endgroup$ Nov 23, 2015 at 16:45
7
$\begingroup$

Based on your example, I think the right SAS syntax to do it by bit manipulation would be something like

if BAND(ethnicity, 32) ^= 0 then white = "Yes"; 
if BAND(ethnicity, 16) ^= 0 then pacific_islander = "Yes"; 
if BAND(ethnicity, 8) ^= 0 then black = "Yes"; 
if BAND(ethnicity, 4) ^= 0 then asian = "Yes"; 
if BAND(ethnicity, 2) ^= 0 then american_indian = "Yes"; 
if BAND(ethnicity, 1) ^= 0 then hispanic = "Yes"; 

Note that this works because

 1 = blshift(1,0)
 2 = blshift(1,1)
 4 = blshift(1,2)
 8 = blshift(1,3)
16 = blshift(1,4)
32 = blshfit(1,5)

which could come handy if you need to do more complex processing where a loop would be nicer than repeating the same code six times.

$\endgroup$
1
  • $\begingroup$ Awesome! That's even simpler than the solution that I added to my question. I really appreciate your insight! $\endgroup$ Nov 23, 2015 at 17:04
2
$\begingroup$

What you do is look at your numbers in binary. For example, $$ 5_{10} = 101_{2}, $$ so hispanic and asian would be true, all others -- false.

$\endgroup$
1
$\begingroup$

$$0\leq N\leq63$$ $$N=\sum_{k=0}^{5}a_k\cdot 2^k$$ $$a_5 = \left[\frac{N}{2^5}\right]$$ $$a_4 = \left[\frac{\mod (N,2^5)}{2^4}\right]$$ $$...$$ $$a_k = \left[\frac{\mod (N,2^{k+1})}{2^k}\right]$$ $$...$$ $$a_0 = \left[\frac{\mod (N,2)}{1}\right]$$

This can be done concurrently for all $k$. (No need to wait for remainder from the previous stage.)

$\endgroup$
1
$\begingroup$

Open MS Excel. Type $DEC2BIN(5)$, for example, if $5$ is the number of the person. Each $1$ or $0$ tells you whether the person belongs to the race or not.

$\endgroup$
2
  • $\begingroup$ Thanks, for some reason bin is not a function that exists in my Excel. But this helps me understand that a solution will be something like converting the number to binary and then checking for a 1 in each position. $\endgroup$ Nov 23, 2015 at 16:16
  • $\begingroup$ @SarahHailey Sorry, I got the function wrong. $\endgroup$ Nov 23, 2015 at 16:19
1
$\begingroup$

I don't know about SAS, but most programming languages have a bitwise AND operator. This is usually the word AND or the symbol & (the symbol && behaves slightly differently as it compares only TRUE and FALSE.) Thus there is no need to actually convert into a human readable binary.

Thus for a person identifying as american indian / white 100010 (34 decimal) assigned we get

a=34

Hispanic          a&1=0
American Indian   a&2=2
Asian             a&4=0
Black             a&8=0
Pacific Island    a&16=0
White             a&32=32

In many languages (C, Python, etc) a nonzero value will be interpreted as TRUE (truthy) and a zero value will be interpreted as FALSE (falsy).

In other languages, the behaviour may be different. For example in Ruby all values (including zero) are considered truthy, with the only exceptions being NIL (absence of data) and the FALSE itself. So we get slightly different code:

C:

if(a&4)puts("Asian");

Ruby:

puts "Asian" if a&4>0
$\endgroup$
-1
$\begingroup$

hispanic(1)
american_indian_or_alaska_native(2)
asian(4)
black_or_african_american(8) native_hawaiian_or_other_pacific_islander(16)
white(32)
An example (not an entire program, just a routine) for QB64:
[
IF (yourcode%% = 0) THEN
-->PRINT "no preference"
ELSE
-->FOR i%% = 0 TO 5
----->j%% = 2 ^ i%%
----->IF (j%% AND yourcode%%) THEN
-------->SELECT CASE j%%
----------->CASE 1: v\$ = "hisp"
----------->CASE 2: v\$ = "amer"
----------->CASE 4: v\$ = "asian"
----------->CASE 8: v\$ = "black"
----------->CASE 16: v\$ = "pacific"
----------->CASE 32: v\$ = "white"
-------->END SELECT
-------->PRINT v\$
----->END IF
-->NEXT 'i%%
END IF
]
You can abbreviate your categories or spell them out in full. All pertinent categories will be listed for a given code.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .