Spriggsy
Spriggsy

Reputation: 306

Encode UINT64 to a float

I have code in C# that converts an UInt64 to a float, the entered value is for example '4537294320117481472'. The code that does the work is in the first block, the second block shows the relevant functions, and the answers are at the bottom.

byte[] rawParameterData = new byte[8];

Console.Write("Enter Value:  ");
string rawDataString = Console.ReadLine();
UInt64 rawParameterInteger = UInt64.Parse(rawDataString);

rawParameterData = ConvertFromUInt64(rawParameterInteger);

float convertedParameterData = ConvertToFloat(rawParameterData, 0);

rawParameterData now equals a byte array of [62,247,181,37,0,0,0,0]

convertedParameterData now equals 0.4838039

public static byte[] ConvertFromUInt64(UInt64 data)
{
    var databuf = BitConverter.GetBytes(data);
    return SwapBytes(databuf, 8);   // DIS is big-endian; need to convert to little-endian: least significant byte is at lower byte location.
}

static float ConvertToFloat(byte[] data, int offset)
{
    var databuf = CopyData(data, offset, 4);
    return BitConverter.ToSingle(databuf, 0);
}


static byte[] SwapBytes(byte[] srcbuf, int datalength)
{
    var destbuf = new byte[srcbuf.Length];
    for (var i = 0; i < datalength; i++)
        destbuf[datalength - 1 - i] = srcbuf[i];
    return destbuf;
}

It seems that the code is relying on the BitConverter.ToSingle(databuf, 0) function that is part of C#.

Can this be done in Python? Thanks.

Upvotes: 2

Views: 161

Answers (2)

silleknarf
silleknarf

Reputation: 1219

import struct
import math 

# We only care about the first 4 of eight of the digits so we 
# need to shift by the character size * number of characters
# then we will just have databuf in our significantBits variable
# So we are converting from: 3E F7 B5 25 0 0 0 0 to 3E F7 B5 25
characterWidth = 8
significantBits = 4537294320117481472 >> (characterWidth * 4)

# We can use this python function convert from bits to a float
# Taken from https://stackoverflow.com/a/14431225/825093 
def bitsToFloat(b):
    s = struct.pack('>l', b)
    return struct.unpack('>f', s)[0]

float = bitsToFloat(significantBits)
print(float) # 0.483803898096

Upvotes: 0

georg
georg

Reputation: 215009

In python, this is as simple as

import struct

a = 4537294320117481472

b = struct.pack('Q', a)
f = struct.unpack('ff', b)

print(f)  # (0.0, 0.4838038980960846)

https://docs.python.org/3/library/struct.html

Upvotes: 3

Related Questions