23 using System.Runtime.InteropServices;
25 namespace SiliconStudio.Core.Mathematics
31 internal class HalfUtils
34 [StructLayout(LayoutKind.Explicit, Pack = 4)]
35 private struct FloatToUint
38 public uint uintValue;
40 public float floatValue;
48 public static float Unpack(ushort h)
50 var conv =
new FloatToUint();
51 conv.uintValue = HalfToFloatMantissaTable[HalfToFloatOffsetTable[h >> 10] + (((uint)h) & 0x3ff)] + HalfToFloatExponentTable[h >> 10];
52 return conv.floatValue;
60 public static ushort Pack(
float f)
62 FloatToUint conv =
new FloatToUint();
64 return (ushort)(FloatToHalfBaseTable[(conv.uintValue >> 23) & 0x1ff] + ((conv.uintValue & 0x007fffff) >> FloatToHalfShiftTable[(conv.uintValue >> 23) & 0x1ff]));
67 static readonly uint[] HalfToFloatMantissaTable =
new uint[2048];
68 static readonly uint[] HalfToFloatExponentTable =
new uint[64];
69 static readonly uint[] HalfToFloatOffsetTable =
new uint[64];
70 static readonly ushort[] FloatToHalfBaseTable =
new ushort[512];
71 static readonly byte[] FloatToHalfShiftTable =
new byte[512];
84 HalfToFloatMantissaTable[0] = 0;
87 for (i = 1; i < 1024; i++)
89 uint m = ((uint)i) << 13;
92 while ((m & 0x00800000) == 0)
99 HalfToFloatMantissaTable[i] = m | e;
103 for (i = 1024; i < 2048; i++)
104 HalfToFloatMantissaTable[i] = 0x38000000 + (((uint)(i - 1024)) << 13);
109 HalfToFloatExponentTable[0] = 0;
111 for (i = 1; i < 63; i++)
114 HalfToFloatExponentTable[i] = ((uint)i) << 23;
116 HalfToFloatExponentTable[i] = 0x80000000 + (((uint)(i - 32)) << 23);
118 HalfToFloatExponentTable[31] = 0x47800000;
119 HalfToFloatExponentTable[32] = 0x80000000;
120 HalfToFloatExponentTable[63] = 0xC7800000;
123 HalfToFloatOffsetTable[0] = 0;
124 for (i = 1; i < 64; i++)
125 HalfToFloatOffsetTable[i] = 1024;
126 HalfToFloatOffsetTable[32] = 0;
132 for (i = 0; i < 256; i++)
137 FloatToHalfBaseTable[i | 0x000] = 0x0000;
138 FloatToHalfBaseTable[i | 0x100] = 0x8000;
139 FloatToHalfShiftTable[i | 0x000] = 24;
140 FloatToHalfShiftTable[i | 0x100] = 24;
144 FloatToHalfBaseTable[i | 0x000] = (ushort)((0x0400 >> (-e - 14)));
145 FloatToHalfBaseTable[i | 0x100] = (ushort)((0x0400 >> (-e - 14)) | 0x8000);
146 FloatToHalfShiftTable[i | 0x000] = (byte)(-e - 1);
147 FloatToHalfShiftTable[i | 0x100] = (byte)(-e - 1);
151 FloatToHalfBaseTable[i | 0x000] = (ushort)(((e + 15) << 10));
152 FloatToHalfBaseTable[i | 0x100] = (ushort)(((e + 15) << 10) | 0x8000);
153 FloatToHalfShiftTable[i | 0x000] = 13;
154 FloatToHalfShiftTable[i | 0x100] = 13;
158 FloatToHalfBaseTable[i | 0x000] = 0x7C00;
159 FloatToHalfBaseTable[i | 0x100] = 0xFC00;
160 FloatToHalfShiftTable[i | 0x000] = 24;
161 FloatToHalfShiftTable[i | 0x100] = 24;
165 FloatToHalfBaseTable[i | 0x000] = 0x7C00;
166 FloatToHalfBaseTable[i | 0x100] = 0xFC00;
167 FloatToHalfShiftTable[i | 0x000] = 13;
168 FloatToHalfShiftTable[i | 0x100] = 13;