nickva commented on issue #4650:
URL: https://github.com/apache/couchdb/issues/4650#issuecomment-1603205176

   To go with float base-2 exponential binning (to capture as much range as 
possible in each counters array) threw this together:
   
   ```erlang
   -define(EXPONENT_BIAS, 1023).
   -define(MANTISSA_BITS, 52).
   -define(EXPONENT_BITS, 11).
   ​
   bin_index(Val, Scale) when is_integer(Val) ->
       bin_index(float(Val), Scale);
   bin_index(Val, Scale) when is_float(Val), is_integer(Scale), Scale >=0, 
Scale < ?MANTISSA_BITS ->
       {Exponent, Mantissa} = exp(Val),
       ExponentBits = Exponent bsl Scale,
       MantissaBits = Mantissa bsr (?MANTISSA_BITS - Scale),
       ExponentBits bor MantissaBits.
   ​
   exp(Val) when is_float(Val) ->
       <<0:1, Exponent:?EXPONENT_BITS, Mantissa:?MANTISSA_BITS>> = 
<<Val/float>>,
       {Exponent - ?EXPONENT_BIAS, Mantissa}.
   ```
   
   At first thought of using just the exponent part directly, however the bins 
are spaced out a bit too much. So then used the idea from 
https://github.com/newrelic-experimental/newrelic-sketch-java/tree/main/src/main/java/com/newrelic/nrsketch/indexer
 to add some more precision from the mantissa part into the bin index.
   
   First exponent is shifted a bit "to make some room" for the extra bits 
`Exponent bsl Scale`. `eeee bsl 2` => `eeee00`. Now we have a place for the 2 
extra precision bits.
   
   Then, we shift the mantissa bits to the right and leave only its two top 
most significant bits. For example, `mmmmmm... bsr (52 -2)` => `0000mm`. And 
finally, combine it by OR-ing into the shifted exponent part to get the index 
`eeee00 bor 0000mm` => `eeeemm`.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to