Netduino home hardware projects downloads community

Jump to content


Photo

Convert byte[4] to float


  • Please log in to reply
11 replies to this topic

#1 laurens

laurens

    New Member

  • Members
  • Pip
  • 2 posts

Posted 09 December 2011 - 09:56 PM

Hello, i am trying to convert a byte array with 4 bytes in it to a float

Since you can't use system.bitconvert.ToSingle() in netduino i tried to make a similar method but without success
these are the following methods i used:

        public static float ToFloat(byte[] buffer)
        {
            return (float)(buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]);
        }

        public static double ToFloat1(byte[] value)
        {
            return (
                value[0] << 0 |
                value[1] << 8 |
                value[2] << 16 |
                value[3] << 24);
        }

        public static unsafe float ToFloat2(byte[] buffer)
        {
            float test = 0;
            fixed (byte* pBuffer = buffer)
            {
                test = *((float*)pBuffer);
            }
            return test;
        }

        public static unsafe float ToFloat3(ref byte[] buffer)
        {
            uint value = Utility.ExtractValueFromArray(buffer, 0, 4);
            return *((float*)&value);

        }

        public static unsafe float ToFloat4(byte[] value)
        {
            int i = (int)Utility.ExtractValueFromArray(value, 0,4);
            return *(((float*)&i));
        }

I tried the following values:
byte[] buffer = new Byte[4]:
buffer[0] = 118;
buffer[1] = 36;
buffer[2] = 27;
buffer[3] = 193;
float test = System.BitConverter.ToSingle(buffer, 0);

This gives -9,696402 if i use this in a plain C# console project.
I also tried to parse string to a double but this method isn't implemented yet.
Basically I need to transfer a rational number from an arduino to a netduino using a serial connection.
I already programmed the arduino to send the floats as an array of 4 bytes which i then read into a buffer on the netduino.
I checked the bytes in the buffer and they forming the correct number using System.BitConverter.ToSingle(buffer, 0); in a C# console.

Feel free to to make suggestions or
Thanks in advance

#2 Coding Smackdown

Coding Smackdown

    Advanced Member

  • Members
  • PipPipPip
  • 78 posts
  • LocationLewisville, TX USA

Posted 09 December 2011 - 11:08 PM

Here are a couple of links that discuss this process in some detail that might help you to make your routine more efficient. The last link actually has an entire library to provide the missing functionality for all of the decimal types. http://www.eggheadca...bledecimal.aspx and http://bloggingabout...-framework.aspx Hope it helps
Brewing Award Winning Beer with a Netduino!
http://diybrewery.com

#3 laurens

laurens

    New Member

  • Members
  • Pip
  • 2 posts

Posted 10 December 2011 - 05:02 PM

Ty coding smackdown for the links However the library uses Math.Pow & Math.Sqrt which are bot not yet implemented, anyone got another suggestion or class that got the function for converting the byte[] to float/double or perhaps some methods for sqrt/pow. I've been searching for some on google but most are too slow & incorrect.

#4 Paul Newton

Paul Newton

    Advanced Member

  • Members
  • PipPipPip
  • 702 posts
  • LocationBerkshire, UK

Posted 10 December 2011 - 09:45 PM

Hi Laurens I am a complete neewbie to C#. I mainly only deal with assembler/C/C++ using fixed point arithmetic. Its very rare that I use a float or a double. So I was intrigued at what you were doing, and after a while it became a matter of honour to find a solution - even if it took me all day. (I think it actually took about 4 hours.) I found some test data on the MSDN site http://msdn.microsof...single.aspx#Y32 and I used this to test my code. Its not quite perfect - see the results in the comment at the end. Its not the most elegant but I think it might get you started. (I used a pair of 16 word lookup tables to avoid using a POW or SQRT function.) File attached. Paul

Attached Files



#5 baxter

baxter

    Advanced Member

  • Members
  • PipPipPip
  • 409 posts

Posted 10 December 2011 - 11:31 PM

This is the way to do it by hand. It shouldn't be too difficult to code this in the Micro Framework.

Conversion from Floating Point Representation to Decimal

http://www.cs.cornel...ng.html#hex2dec
Array assumed little-endian
dec   binary   hex
118 = 01110110 76
36  = 00100100 1e
27  = 00011011 1b
193 = 11000001 c1

reverse array to get floating point representation (or work backwards)

c11b1e76
11000001000110110001111001110110

sign              exponent              mantissa
1                 10000010              1.00110110001111001110110
^                   ^                   ^
|                   |                   |
one = negative   (130-127) exp =2^3     implied one

-1.00110110001111001110110 <-- convert this
 ^ ^^
 0 123456789 ... position = negative powers of two

-(2^0 + 2^-3 + 2^-4 + 2^-6 + 2^-7 + 2^-11 ...)*2^3

 -(8 + 1 + 1/2  + 0.125 + 0.0625 + 0.00390625  ...) = -9.69140625...
Baxter

#6 Luke Cummings

Luke Cummings

    Advanced Member

  • Members
  • PipPipPip
  • 38 posts
  • LocationCalgary, AB

Posted 18 December 2011 - 10:17 PM

Just for sake of it, here is the code I was using for my quad copter project. Of all my testing this ended up being the fastest. http://code.tinyclr....4/bitconverter/
Cheap, Fast, Good... Pick two

#7 baxter

baxter

    Advanced Member

  • Members
  • PipPipPip
  • 409 posts

Posted 19 December 2011 - 04:32 AM

Hi Luke, I converted your code to a DLL, imported it into Visual Basic and it works like a charm. All other unsafe code I tried trashed my Netduino. Thanks for providing this badly needed functionality. Baxter

#8 Paul Newton

Paul Newton

    Advanced Member

  • Members
  • PipPipPip
  • 702 posts
  • LocationBerkshire, UK

Posted 19 December 2011 - 08:45 AM

Just for sake of it, here is the code I was using for my quad copter project. Of all my testing this ended up being the fastest.

http://code.tinyclr....4/bitconverter/


Hi Luke,

I'm used to programming in C & C++ where almost all code is "unsafe", however this is generally OK because the programmer is in control of the program's memory.

I understand some of the risks of using pointers to access data in .Net, what I am unsure of is just how unsafe unsafe is.
Am I correct to assume that the only risk in using unsafe code to read memory is that the wrong value may be returned?
What is the likely-hood that something goes wrong that can cause an exception?
Are there things that can be done to mitigate the risks? e.g. is is possible to prevent .Net making changes to the memory in the background during an unsafe function call?

Paul

#9 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1717 posts
  • LocationVenezia, Italia

Posted 19 December 2011 - 12:49 PM

@Paul: I agree on the weak-unsafety of the C#'s "unsafe". Compared to C/C++, the "unsafe" ability to create disasters is bomb-proof! Anyway, it seems that the pointers (I guess the unsafe-stuffs as well) are not supported. That's a pity for a low-level environment such a the MF. Cheers
Biggest fault of Netduino? It runs by electricity.

#10 Luke Cummings

Luke Cummings

    Advanced Member

  • Members
  • PipPipPip
  • 38 posts
  • LocationCalgary, AB

Posted 19 December 2011 - 10:56 PM

Hi Luke,

I'm used to programming in C & C++

...

e.g. is is possible to prevent .Net making changes to the memory in the background during an unsafe function call?

Paul


Paul,

Pointers in C# using the unsafe construct are just as dangerous as in any other case. For example check out how I managed to brick my FEZ panda on this thread: http://www.tinyclr.com/forum/12/2700/. Using pointers gives you unfettered access to any memory you choose.

Really my mistake could have been made whether I was using managed or native code. Once you start getting into more advanced topics, like accessing various chip features (ie IAP on the NXP chip that GHI uses for USBizi) it becomes risky, especially when you know just enough to get yourself in trouble ;)

edit:
@Mario: you are correct about it not being supported, but I've never had an issue using it. In this case my conversions were 3 times faster than anything else I could come up with.

-Luke
Cheap, Fast, Good... Pick two

#11 Luke Cummings

Luke Cummings

    Advanced Member

  • Members
  • PipPipPip
  • 38 posts
  • LocationCalgary, AB

Posted 19 December 2011 - 11:08 PM

Hi Luke,

I converted your code to a DLL, imported it into Visual Basic and it works like a charm. All other unsafe code I tried trashed my Netduino. Thanks for providing this badly needed functionality.

Baxter


Glad I could help. There definitely are some 'gotchas' using this technique.
Cheap, Fast, Good... Pick two

#12 Luke Cummings

Luke Cummings

    Advanced Member

  • Members
  • PipPipPip
  • 38 posts
  • LocationCalgary, AB

Posted 19 December 2011 - 11:11 PM

I would hate to drive traffic on a rival site so for fairness, here is the bitconverter class.

Attached Files


Cheap, Fast, Good... Pick two




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2010-2014 Secret Labs LLC  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.