static unsafe float CalcHalfToSingle(FP16 floatHalfPrecision) { uint result = mantissaTable[offsetTable[floatHalfPrecision.Value >> 10] + (floatHalfPrecision.Value & 0x3ff)] + exponentTable[floatHalfPrecision.Value >> 10]; float v1 = *((float *)&result); return(v1); }
internal static unsafe FP16 SingleToHalf(float single) { uint value = *((uint *)&single); ushort result = (ushort)(baseTable[(value >> 23) & 0x1ff] + ((value & 0x007fffff) >> shiftTable[value >> 23])); return(FP16.ToHalf(result)); }
static void InitializeLookup() { LOOKUP = new float[ushort.MaxValue + 1]; for (int i = 0; i <= ushort.MaxValue; i++) { FP16 fp16 = new FP16((ushort)i, true); LOOKUP[i] = CalcHalfToSingle(fp16); } }
internal static unsafe float HalfToSingle(FP16 floatHalfPrecision) { #if NOT // slower CheckLOOKUPInitialized(); return(LOOKUP[floatHalfPrecision.Value]); #endif uint result = mantissaTable[offsetTable[floatHalfPrecision.Value >> 10] + (floatHalfPrecision.Value & 0x3ff)] + exponentTable[floatHalfPrecision.Value >> 10]; return(*((float *)&result)); }
internal static bool IsNegativeInfinity(FP16 floatHalfPrecision) => floatHalfPrecision.Value == 0xfc00;
internal static bool IsInfinity(FP16 floatHalfPrecision) => (floatHalfPrecision.Value & 0x7fff) == 0x7c00;
internal static bool IsNaN(FP16 floatHalfPrecision) => (floatHalfPrecision.Value & 0x7fff) > 0x7c00;
internal static FP16 Abs(FP16 floatHalfPrecision) => FP16.ToHalf((ushort)(floatHalfPrecision.Value & 0x7fff));
internal static FP16 Negate(FP16 floatHalfPrecision) => FP16.ToHalf((ushort)(floatHalfPrecision.Value ^ 0x8000));
internal static unsafe float HalfToSingleLookup(FP16 floatHalfPrecision) { return(LOOKUP[floatHalfPrecision.Value]); }