www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to convert from ubyte[] to and from float?

reply Charles Hixson via Digitalmars-d-learn writes:
What is the best way to convert from a part of a ubyte[] to a float?

I've tried converting the ubyte[] into a uint, but neither casting the 
uint to a float nor to!float work.

I suppose I could use a "trick record" union, but that seems inelegant.  
If I use pointers, the alignment may (unpredictably) not be proper 
(whatever that means these days).
Oct 18 2014
next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 10/18/2014 06:06 PM, Charles Hixson via Digitalmars-d-learn wrote:
 What is the best way to convert from a part of a ubyte[] to a float?

 I've tried converting the ubyte[] into a uint, but neither casting the
 uint to a float nor to!float work.

 I suppose I could use a "trick record" union, but that seems inelegant.
 If I use pointers, the alignment may (unpredictably) not be proper
 (whatever that means these days).
This is what I understood: import std.exception; ubyte[float.sizeof] toBytes(float f) { ubyte* beg = cast(ubyte*)&f; return beg[0..f.sizeof]; } float toFloat(const(ubyte)[] bytes) { enforce(bytes.length >= float.sizeof); return *cast(float*)bytes.ptr; } void main() { float f = 1.5; auto bytes = toBytes(f); float f2 = toFloat(bytes); assert(f2 == f); } There are no alignment issues because f and ubyte[float.sizeof] are not related. If you meant that ubyte[] should be a reference to an existing float, then toBytes must take by 'ref float' and then it can return a ubyte[]. However, it would be the responsibility of the caller to ensure that the float would live long enough. If that happened, then there would be no alignment issues because we would have started with a float anyway and the ubyte[] would be referring to that float in memory. Ali
Oct 18 2014
prev sibling parent "uri" <uri gmail.com> writes:
On Sunday, 19 October 2014 at 03:14:26 UTC, Charles Hixson via 
Digitalmars-d-learn wrote:
 What is the best way to convert from a part of a ubyte[] to a 
 float?

 I've tried converting the ubyte[] into a uint, but neither 
 casting the uint to a float nor to!float work.

 I suppose I could use a "trick record" union, but that seems 
 inelegant.  If I use pointers, the alignment may 
 (unpredictably) not be proper (whatever that means these days).
Is this what you're after? http://dlang.org/phobos/std_bitmanip.html#.peek http://dlang.org/phobos/std_bitmanip.html#.read http://dlang.org/phobos/std_bitmanip.html#.write These accept indices, or you can just slice the ubyte[] to the part you need. --- import std.stdio; import std.bitmanip; import std.system; void main() { // UBYTE[] to FLOAT // // 6.5535000E+004 00-FF-7F-47 ubyte[] ubval = [0, 0xff, 0x7f, 0x47]; auto fval = ubval.peek!(float, Endian.littleEndian); writefln("%s as float: %s", ubval, fval); writefln("%s as float: %s", ubval, ubval.read!(float, Endian.littleEndian)); // 16383.8 00-FF-7F-46 ubval = [0, 0xff, 0x7f, 0x46]; fval = ubval.peek!(float, Endian.littleEndian); writefln("%s as float: %s", ubval, fval); writefln("%s as float: %s", ubval, ubval.read!(float, Endian.littleEndian)); // FLOAT to UBYTE[] ubval = [0, 0, 0, 0]; std.bitmanip.write!(float, Endian.littleEndian)(ubval, 65535.0f, 0); writefln("%s as ubyte[]: %s", fval, ubval); ubval = [0, 0, 0, 0]; std.bitmanip.write!(float, Endian.littleEndian)(ubval, fval, 0); writefln("%s as ubyte[]: %s", fval, ubval); } ---
Oct 19 2014