Lucene.Net  3.0.3
Lucene.Net is a port of the Lucene search engine library, written in C# and targeted at .NET runtime users.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Pages
SmallFloat.cs
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 using System;
19 
20 namespace Lucene.Net.Util
21 {
22 
23 
24  /// <summary>Floating point numbers smaller than 32 bits.
25  ///
26  /// </summary>
27  /// <version> $Id$
28  /// </version>
29  public class SmallFloat
30  {
31 
32  /// <summary>Converts a 32 bit float to an 8 bit float.
33  /// <br/>Values less than zero are all mapped to zero.
34  /// <br/>Values are truncated (rounded down) to the nearest 8 bit value.
35  /// <br/>Values between zero and the smallest representable value
36  /// are rounded up.
37  ///
38  /// </summary>
39  /// <param name="f">the 32 bit float to be converted to an 8 bit float (byte)
40  /// </param>
41  /// <param name="numMantissaBits">the number of mantissa bits to use in the byte, with the remainder to be used in the exponent
42  /// </param>
43  /// <param name="zeroExp">the zero-point in the range of exponent values
44  /// </param>
45  /// <returns> the 8 bit float representation
46  /// </returns>
47  public static sbyte FloatToByte(float f, int numMantissaBits, int zeroExp)
48  {
49  // Adjustment from a float zero exponent to our zero exponent,
50  // shifted over to our exponent position.
51  int fzero = (63 - zeroExp) << numMantissaBits;
52  int bits = System.BitConverter.ToInt32(System.BitConverter.GetBytes(f), 0);
53  int smallfloat = bits >> (24 - numMantissaBits);
54  if (smallfloat < fzero)
55  {
56  return (bits <= 0)?(sbyte) 0:(sbyte) 1; // underflow is mapped to smallest non-zero number.
57  }
58  else if (smallfloat >= fzero + 0x100)
59  {
60  return - 1; // overflow maps to largest number
61  }
62  else
63  {
64  return (sbyte) (smallfloat - fzero);
65  }
66  }
67 
68  /// <summary>Converts an 8 bit float to a 32 bit float. </summary>
69  public static float ByteToFloat(byte b, int numMantissaBits, int zeroExp)
70  {
71  // on Java1.5 & 1.6 JVMs, prebuilding a decoding array and doing a lookup
72  // is only a little bit faster (anywhere from 0% to 7%)
73  if (b == 0)
74  return 0.0f;
75  int bits = (b & 0xff) << (24 - numMantissaBits);
76  bits += ((63 - zeroExp) << 24);
77  return BitConverter.ToSingle(BitConverter.GetBytes(bits), 0);
78  }
79 
80 
81  //
82  // Some specializations of the generic functions follow.
83  // The generic functions are just as fast with current (1.5)
84  // -server JVMs, but still slower with client JVMs.
85  //
86 
87  /// <summary>floatToByte(b, mantissaBits=3, zeroExponent=15)
88  /// <br/>smallest non-zero value = 5.820766E-10
89  /// <br/>largest value = 7.5161928E9
90  /// <br/>epsilon = 0.125
91  /// </summary>
92  public static sbyte FloatToByte315(float f)
93  {
94  int bits = System.BitConverter.ToInt32(System.BitConverter.GetBytes(f), 0);
95  int smallfloat = bits >> (24 - 3);
96  if (smallfloat < (63 - 15) << 3)
97  {
98  return (bits <= 0)?(sbyte) 0:(sbyte) 1;
99  }
100  if (smallfloat >= ((63 - 15) << 3) + 0x100)
101  {
102  return - 1;
103  }
104  return (sbyte) (smallfloat - ((63 - 15) << 3));
105  }
106 
107  /// <summary>byteToFloat(b, mantissaBits=3, zeroExponent=15) </summary>
108  public static float Byte315ToFloat(byte b)
109  {
110  // on Java1.5 & 1.6 JVMs, prebuilding a decoding array and doing a lookup
111  // is only a little bit faster (anywhere from 0% to 7%)
112  if (b == 0)
113  return 0.0f;
114  int bits = (b & 0xff) << (24 - 3);
115  bits += ((63 - 15) << 24);
116  return BitConverter.ToSingle(BitConverter.GetBytes(bits), 0);
117  }
118 
119 
120  /// <summary>floatToByte(b, mantissaBits=5, zeroExponent=2)
121  /// <br/>smallest nonzero value = 0.033203125
122  /// <br/>largest value = 1984.0
123  /// <br/>epsilon = 0.03125
124  /// </summary>
125  public static sbyte FloatToByte52(float f)
126  {
127  int bits = System.BitConverter.ToInt32(System.BitConverter.GetBytes(f), 0);
128  int smallfloat = bits >> (24 - 5);
129  if (smallfloat < (63 - 2) << 5)
130  {
131  return (bits <= 0)?(sbyte) 0:(sbyte) 1;
132  }
133  if (smallfloat >= ((63 - 2) << 5) + 0x100)
134  {
135  return - 1;
136  }
137  return (sbyte) (smallfloat - ((63 - 2) << 5));
138  }
139 
140  /// <summary>byteToFloat(b, mantissaBits=5, zeroExponent=2) </summary>
141  public static float Byte52ToFloat(byte b)
142  {
143  // on Java1.5 & 1.6 JVMs, prebuilding a decoding array and doing a lookup
144  // is only a little bit faster (anywhere from 0% to 7%)
145  if (b == 0)
146  return 0.0f;
147  int bits = (b & 0xff) << (24 - 5);
148  bits += ((63 - 2) << 24);
149  return BitConverter.ToSingle(BitConverter.GetBytes(bits), 0);
150  }
151  }
152 }