static double ExtractSignalFromBytes(byte[] bytes, Message.Signal signal) { int startByte = (int)signal.StartBit / 8; int startBit = (int)signal.StartBit % 8; int numBits = (int)signal.BitSize; Debug.Assert(numBits > 0); Debug.Assert(signal.ByteOrder == Message.Signal.ByteOrderEnum.LittleEndian); Debug.Assert(numBits < 64); long totalInteger = 0; bool negative = false; int bitsConsumed = 0; while (numBits > 0) { int bitsToConsume = Math.Min(numBits, 8 - startBit); int mask = ((1 << bitsToConsume) - 1); int v = bytes[startByte]; v >>= startBit; v &= mask; v <<= bitsConsumed; totalInteger += v; if (signal.ValueType == Message.Signal.ValueTypeEnum.Signed) { if (bitsToConsume == numBits) { int hibit = (1 << (numBits - 1)); if ((v & hibit) != 0) { negative = true; } } } bitsConsumed += bitsToConsume; numBits -= bitsToConsume; startBit = 0; startByte++; } double totalDouble = totalInteger; if (negative) { totalDouble -= (1 << bitsConsumed); } totalDouble *= signal.ScaleFactor; totalDouble += signal.Offset; return(totalDouble); }
static double ExtractSignalFromBytes(byte[] bytes, Message.Signal signal) { UInt64 signalMask = 0; for (int bit_index = (int)(signal.StartBit + signal.BitSize - 1); bit_index >= 0; --bit_index) { signalMask <<= 1; if (bit_index >= signal.StartBit) { signalMask |= 1; } } UInt64 signalValueRaw = 0; for (int byte_index = bytes.Length - 1; byte_index >= 0; --byte_index) { signalValueRaw <<= 8; signalValueRaw += bytes[byte_index]; } signalValueRaw &= signalMask; if (signal.ByteOrder == Message.Signal.ByteOrderEnum.BigEndian) { signalMask = ByteSwap64(signalMask); signalValueRaw = ByteSwap64(signalValueRaw); } while ((signalMask & 0x1) == 0) { signalValueRaw >>= 1; signalMask >>= 1; } double signalValue = signalValueRaw; if (signal.ValueType == Message.Signal.ValueTypeEnum.Signed) { UInt64 signalMaskHighBit = (signalMask + 1) >> 1; if ((signalValueRaw & signalMaskHighBit) != 0) { signalValue = -(Int64)((signalValueRaw ^ signalMask) + 1); } } signalValue *= signal.ScaleFactor; signalValue += signal.Offset; return(signalValue); }