Search code examples
c#.netcastingfloating-pointintptr

Is it possible to determine if an IntPtr is pointing to a 32-bit or to a 64-bit float?


If an arbitrary IntPtr is received in .NET (C#), is it possible to determine if it is pointing to a 32-bit or 64-bit float and safely convert it to the .NET float type? Or is explicit knowledge of the type required?


Solution

  • In the most general case, no it isn't possible. The first four bytes of an eight byte (double precision) value have some meaning when interpreted as if they were a single precision value.

    However, if you have some additional knowledge (e.g. the values always fall within a certain range / are always finite) then you may be able to differentiate between "four bytes are a single precision value" and "four bytes are a partial read of a double precision value". It's going to need a lot of luck (regarding the restrictions on the data you expect to receive) to actually turn this into a detection algorithm.

    In some cases, you may be able to infer size from the pointer alignment. Four byte alignment is definitely not a double precision value. Eight byte alignment can be either precision, though, so this isn't reliable. But it may be useful to save you from reading extra bytes beyond the edge of a page and causing an access violation.

    If you want to head down this path (being aware that for some data, you might not be able to decide for sure, and maintenance is not going to be fun), you can use Marshal.Copy to grab the data into a byte array, and then do bit tests on that as well as BitConverter to interpret them as floating-point values of different precisions. Be sure to get familiar with IEEE encoding of floating-point numbers, biased encoding of exponents, etc.

    At the other extreme, if you're being passed an array of data and given only the length in bytes, but not the number of elements/size of each element, you have a very good chance of identifying the repetition pattern and deducing the precision.

    Bottom line: This isn't a good way to build software for deployment. But if you are writing throw-away code to deal with a particular dataset, and the code will never leave your hands, there's a chance you can succeed.