Ahnen numbers, commonly used in ahnenlists and ahnentafels, are easily translated into a description of the relationship of the ancestor to the focus person (number 1). For example, number 24 signifies a 2xgreatgrandfather on my mother's side.

I want to use these numbers to extract information about the relationship between two ancestors other than the focus person. For example, what is the family relationship between person 9 and person 78.

One method is to redraw the pedigree with a new focus (by moving the person who was 9 to position 1) and finding the other person is now at position 14. However, I am interested in a numerical method that can be applied to any pair of values.

To restate:

Given an ahnen-numbered ancestral report of a third person, in which person A is assigned number m and person B is number n; what is the ahnen number of person B in the ancestral report of person A?

The procedure should give one of two answers: (i) undefined (when person B is not a direct ancestor of person A) or (ii) an ahnen number that can translated into a description of the relationship.

  • In the question above, I have tried to balance the correct use of terminology with the need to avoid complex snytax. If you want to take issue with my usage, a 2010 blog post by TamuraJones would be a good place to start.
    – Fortiter
    Oct 23 '12 at 3:16

Answer focus

The following answer deliberately ignores two issues:

  1. The possibility that the ancestors are related in ways not shown in the report.

  2. The possibility that, through pedigree collapse, the same ancestor appears multiple times, and thus has multiple ahnen numbers.

The solution provided merely solves the relationship between two ancestral slots.

Two outcomes

You already remarked that there are two possible outcomes;

  1. An ahnen number that identifies their relationship.
  2. Not related. This can be represented by the value zero.

Some issues

There are some additional points of attention:

  1. erroneous input: an ahnen number is a positive whole number. Zero and negative numbers should be rejected as invalid input.

  2. That A is B's ancestor is one possibility, the other is that B is A's ancestor. If either one is the ancestor of the other, it is the larger number. An algorithm could swap A and B, and negate the return the value to indicate they were swapped.

  3. A and B may be identical. The boundary condition that must be satisfied is: if A and B are identical, the return value must be 1.

  4. Another border case is that A and B are spouses. The result of the algorithm is, correctly, that they are not related; they are not ancestors of each other.


From here on, it is assumed that A (for possible Ancestor) is not smaller than D (for possible Descendent).

The solution requires a small bit of coding, but is conceptually very simple. The key is to consider ahnen numbers in binary notation; for A to be a direct ancestor of D, A's bit pattern must start with the entirety of D's bit pattern.

If the bit patterns do not match, then A isn't an ancestor of D, and the return value is zero. If A does start with D's bit pattern, replace that pattern by 1 to get A's relationship to D. This is effectively calculating A's ahnen number respective to D, i.e. A's number when D is the root.

Quick description of a possible algorithm:

  1. Reject invalid input, ensure A >= D.

  2. N = 0, C = A. While ( C > D ) right-shift C, N++. Now C <= D and N is the number of shifts performed.

  3. If ( C < B ) then the bit patterns do not match. A isn't an ancestor of B, so the result is 0, and we're done. If ( C == B ) we have a match. Continue to next step.

  4. Take only the last N bits of A, and then set the next highest bit (bit N) to 1. Return the resulting number.

Step through for the border-case that ( A == D ):

Because ( C == D ), step 2 performs zero shifts; N == 0. Step 4 takes the last N bits of A; that is the last zero bits (no bits at all), resulting in the value 0, then sets bit 0 to 1. Result becomes 1.

Step through for 9 and 78: A = 78, D = 9

In binary, A is 1001 110, D is 1001 (space inserted in A to highlight how it matches D).

Because ( C != D ), step 2 right-shifts C three times, C becomes 78 >> 3 == 9. Now C is equal to D, so we have a match after three shifts: N = 3. Step 4 takes the last 3 bits of A, and adds a 1 in front of it; 110 becomes 1110 binary. The decimal result is 14. Reading the bits (1110) from right to left gives: father of mother of mother of.


"what is the family relationship between person 9 and person 78"

Person 9 is the great-granddaughter of person 78

Double a person's number to find their father, then add 1 for the mother.

All males (exception #1) are even, and all females are odd.

Person 9's parents are 18 & 19. Grandparents are 36, 37, 38, & 39. Great-grandparents are 72, 73, 74, 75, 76, 77, 78, & 79.

Divide a male by 2 to find the child. Females subtract 1, then divide by 2 to find the child.

Person 78 is the father of 39, 39 is the mother of 19, 19 is the mother of 9.

  • Thanks Rusty, I can carry out any individual example. What I am looking for is a procedure that I can machine program. Is there a way to generalise your method?
    – Fortiter
    Oct 23 '12 at 10:36
  • I think the easiest way would be to group numbers by generation. 1 = gen1, 2-3 = gen2, 4-7 = gen3, 8-15 = gen4, 16-31 = gen5, 32-63 = gen6, 64-127 = gen7 Oct 23 '12 at 10:50

Let's assume that person 2 has the higher ahnen number; it simplifies some of the handling below.

First, get the generations of the two individuals:

gen1 = log2(N1)
gen2 = log2(N2)

Then find the difference in generations:

gendiff = gen1 - gen2

Person 3 is the descendant of person 2 in person 1's generation:

divisor = 2gendiff
N3 = N2/divisor

If N3 is the same as N1, then person 2 is an ancestor of person 1. If not, stop here, the procedure can't continue.

Now re-root the tree, assigning person 1 as N=1. Person 2 will be in the generation starting with Ng=2gendiff. Figure out how many steps to the right to move person 2 by finding person 1's "left most" ancestor in the original tree and then subtracting that NL from N2:

steps = N2 - (N1 * Ng)
N'2 = Ng + steps

As an example, consider persons 6 and 49. Logs tells us these are in generations 2 and 5, so gendiff=3. Dividing the higher number says that they are in the same direct lineage, so we can continue. The leftmost person in 49's generation is 48, so the number of steps to move in the new tree is 1. Ng=8, so N'2=9. Of course, N'1 is always 1.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.