001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.solr.util;
017:
018: /**
019: * @author yonik
020: * @version $Id: NumberUtils.java 472574 2006-11-08 18:25:52Z yonik $
021: */
022: public class NumberUtils {
023:
024: public static String int2sortableStr(int val) {
025: char[] arr = new char[3];
026: int2sortableStr(val, arr, 0);
027: return new String(arr, 0, 3);
028: }
029:
030: public static String int2sortableStr(String val) {
031: return int2sortableStr(Integer.parseInt(val));
032: }
033:
034: public static String SortableStr2int(String val) {
035: int ival = SortableStr2int(val, 0, 3);
036: return Integer.toString(ival);
037: }
038:
039: public static String long2sortableStr(long val) {
040: char[] arr = new char[5];
041: long2sortableStr(val, arr, 0);
042: return new String(arr, 0, 5);
043: }
044:
045: public static String long2sortableStr(String val) {
046: return long2sortableStr(Long.parseLong(val));
047: }
048:
049: public static String SortableStr2long(String val) {
050: long ival = SortableStr2long(val, 0, 5);
051: return Long.toString(ival);
052: }
053:
054: //
055: // IEEE floating point format is defined so that it sorts correctly
056: // when interpreted as a signed integer (or signed long in the case
057: // of a double) for positive values. For negative values, all the bits except
058: // the sign bit must be inverted.
059: // This correctly handles all possible float values including -Infinity and +Infinity.
060: // Note that in float-space, NaN<x is false, NaN>x is false, NaN==x is false, NaN!=x is true
061: // for all x (including NaN itself). Internal to Solr, NaN==NaN is true and NaN
062: // sorts higher than Infinity, so a range query of [-Infinity TO +Infinity] will
063: // exclude NaN values, but a query of "NaN" will find all NaN values.
064: // Also, -0==0 in float-space but -0<0 after this transformation.
065: //
066: public static String float2sortableStr(float val) {
067: int f = Float.floatToRawIntBits(val);
068: if (f < 0)
069: f ^= 0x7fffffff;
070: return int2sortableStr(f);
071: }
072:
073: public static String float2sortableStr(String val) {
074: return float2sortableStr(Float.parseFloat(val));
075: }
076:
077: public static float SortableStr2float(String val) {
078: int f = SortableStr2int(val, 0, 3);
079: if (f < 0)
080: f ^= 0x7fffffff;
081: return Float.intBitsToFloat(f);
082: }
083:
084: public static String SortableStr2floatStr(String val) {
085: return Float.toString(SortableStr2float(val));
086: }
087:
088: public static String double2sortableStr(double val) {
089: long f = Double.doubleToRawLongBits(val);
090: if (f < 0)
091: f ^= 0x7fffffffffffffffL;
092: return long2sortableStr(f);
093: }
094:
095: public static String double2sortableStr(String val) {
096: return double2sortableStr(Double.parseDouble(val));
097: }
098:
099: public static double SortableStr2double(String val) {
100: long f = SortableStr2long(val, 0, 6);
101: if (f < 0)
102: f ^= 0x7fffffffffffffffL;
103: return Double.longBitsToDouble(f);
104: }
105:
106: public static String SortableStr2doubleStr(String val) {
107: return Double.toString(SortableStr2double(val));
108: }
109:
110: // uses binary representation of an int to build a string of
111: // chars that will sort correctly. Only char ranges
112: // less than 0xd800 will be used to avoid UCS-16 surrogates.
113: public static int int2sortableStr(int val, char[] out, int offset) {
114: val += Integer.MIN_VALUE;
115: out[offset++] = (char) (val >>> 24);
116: out[offset++] = (char) ((val >>> 12) & 0x0fff);
117: out[offset++] = (char) (val & 0x0fff);
118: return 3;
119: }
120:
121: public static int SortableStr2int(String sval, int offset, int len) {
122: int val = sval.charAt(offset++) << 24;
123: val |= sval.charAt(offset++) << 12;
124: val |= sval.charAt(offset++);
125: val -= Integer.MIN_VALUE;
126: return val;
127: }
128:
129: // uses binary representation of an int to build a string of
130: // chars that will sort correctly. Only char ranges
131: // less than 0xd800 will be used to avoid UCS-16 surrogates.
132: // we can use the lowest 15 bits of a char, (or a mask of 0x7fff)
133: public static int long2sortableStr(long val, char[] out, int offset) {
134: val += Long.MIN_VALUE;
135: out[offset++] = (char) (val >>> 60);
136: out[offset++] = (char) (val >>> 45 & 0x7fff);
137: out[offset++] = (char) (val >>> 30 & 0x7fff);
138: out[offset++] = (char) (val >>> 15 & 0x7fff);
139: out[offset] = (char) (val & 0x7fff);
140: return 5;
141: }
142:
143: public static long SortableStr2long(String sval, int offset, int len) {
144: long val = (long) (sval.charAt(offset++)) << 60;
145: val |= ((long) sval.charAt(offset++)) << 45;
146: val |= ((long) sval.charAt(offset++)) << 30;
147: val |= sval.charAt(offset++) << 15;
148: val |= sval.charAt(offset);
149: val -= Long.MIN_VALUE;
150: return val;
151: }
152:
153: }
|