[ 
https://issues.apache.org/jira/browse/LUCENE-6480?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14543396#comment-14543396
 ] 

Karl Wright commented on LUCENE-6480:
-------------------------------------

Here are (untested) code snippets for converting a single double value to a 
long and back, such that locality is preserved etc.  In order to use these with 
x,y,z you would need to use a modified three-part Morton encoding (similar to 
what was done for GeoPointField) to interleave the bits resulting from the 
encoding method, and the reverse operation to de-convolve the long into three 
sets of bits.

{code}
  public static long toGeoBits(double value) {
    // Get the bits for the value
    long lvalue = Double.doubleToLongBits(value);
    // The exponent will range from 0 to -1023.  Use it to compute the
    // amount to shift the mantissa.  But shift left one first, so we 
sign-extend properly.
    int exponent = (int)((lvalue << 1) >> 53);
    // Shift the mantissa to the leftmost position and add the hidden bit
    long mantissa = (lvalue & 0x000FFFFFFFFFFFFFL) << 11;
    // Special value of zero occurs when exponent == 0 and mantissa == 0.  But 
a rigorous interpretation
    // of this value is 2^(-1023), which is close enough to zero for our work, 
so we do nothing special.
    long fullMantissa = mantissa | 0x8000000000000000L;
    // Now, compute the amount to shift the mantissa.  We want the mantissa,
    // plus the hidden bit, to wind up in the right place.  This will allow 
room for the sign bit too
    return (mantissa >>> (1024-exponent)) | ((lvalue & 0x8000000000000000L) ^ 
0x8000000000000000L);
  }
  
  protected final static double SHIFT_RIGHT_AMT =
    0.5 * 0.5 * 0.5 * 0.5 * 0.5 * 0.5 * 0.5 * 0.5 *
    0.5 * 0.5 * 0.5 * 0.5 * 0.5 * 0.5 * 0.5 * 0.5 *
    0.5 * 0.5 * 0.5 * 0.5 * 0.5 * 0.5 * 0.5 * 0.5 *
    0.5 * 0.5 * 0.5 * 0.5 * 0.5 * 0.5 * 0.5 * 0.5 *
    0.5 * 0.5 * 0.5 * 0.5 * 0.5 * 0.5 * 0.5 * 0.5 *
    0.5 * 0.5 * 0.5 * 0.5 * 0.5 * 0.5 * 0.5 * 0.5 *
    0.5 * 0.5 * 0.5 * 0.5 * 0.5 * 0.5 * 0.5 * 0.5 *
    0.5 * 0.5 * 0.5 * 0.5 * 0.5 * 0.5 * 0.5;
  
  public static double fromGeoBits(long bits) {
    // To compute the exponent, we need to count the number of "0" bits from 
the next-to-highest position down to
    // the first "1".  This is not trivial to do without a loop, which would 
slow us down.  So a better
    // way to do the job is to just cast from the long to a double, and extract 
the exponent from
    // the result.
    double castedDouble = (double)(bits & 0x7FFFFFFFFFFFFFFFL);
    // We need to divide by 2^63 to get the number back in range, and set the 
appropriate sign.
    castedDouble *= SHIFT_RIGHT_AMT;
    if ((bits & 0x8000000000000000L) == 0)
      return -castedDouble;
    return castedDouble;
  }
{code}

> Extend Simple GeoPointField Type to 3d 
> ---------------------------------------
>
>                 Key: LUCENE-6480
>                 URL: https://issues.apache.org/jira/browse/LUCENE-6480
>             Project: Lucene - Core
>          Issue Type: New Feature
>          Components: core/index
>            Reporter: Nicholas Knize
>
> [LUCENE-6450 | https://issues.apache.org/jira/browse/LUCENE-6450] proposes a 
> simple GeoPointField type to lucene core. This field uses 64bit encoding of 2 
> dimensional points to construct sorted term representations of GeoPoints 
> (aka: GeoHashing).
> This feature investigates adding support for encoding 3 dimensional 
> GeoPoints, either by extending GeoPointField to a Geo3DPointField or adding 
> an additional 3d constructor.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@lucene.apache.org
For additional commands, e-mail: dev-h...@lucene.apache.org

Reply via email to