First of all, "difficulty" as a concept does not exist in the protocol. It's a unit intended only for human consumption.
Internally, the value that corresponds with it is the target. The target is a 256-bit number, computed for every block, and a block is valid if its hash (interpreted as 256-bit number as well) is less than or equal to the target.
The difficulty is simply defined as the (floating-point, approximate) value of MAX_TARGET / target. MAX_TARGET us (216-1)2208, the maximum possible target (so the lowest difficulty Bitcoin will permit for any block).
To compare chains, a new metric is introduced: work. Work is the expected number of hashing attempts are necessary to construct valid proof-of-work for that block. It is simply 2256 divided by the number of potential hash values that meet the target, namely target + 1. So, the work of a block is defined as 2256 / (target + 1).
The work of a chain is simply the sum of the work values of the blocks in it. This makes sense: we want to make sure that an attacker needs to do as much work as the honest miners needed to produce a valid chain.
At block 678033, with approximate difficulty 23137439666472.1, we have:
- Target is 1165190949371886336955396954992052935118810155482873856 (or 0xc2a480000000000000000000000000000000000000000 in hex).
- Work is 99376063039054378510219
- Cumulative work (sum of all work in the entire chain) is approximately 8.565487⋅1027.
So - perhaps remarkably - this is (approximately) equivalent to just summing the difficulty values of all blocks. No logarithms involved.
For completeness, Bitcoin Core's current rules for picking the best chain:
- First exclude all chains with invalid blocks
- Then pick the tips of all those chains, and leave only the ones with the highest cumulative work (which may be more than one if there is a fork).
- Among those, pick the one for which the full block (not just the header) was received first.