#How to read a float (etc) from memory?

1 messages · Page 1 of 1 (latest)

idle gate
#

I am having a lot of trouble trying to read and write values from memory. I am attempting to write a binary format, which seems like something that should be easy in a systems programming language.
in C it's somewhat painful but you can dereference a pointer and assign it to a value and cast anything to anything.
In node.js it's dead simple to do what I want value=buffer.readDoubleLE(offset)
in zig I'm really scratching my head. I see there are methods to read int (which involve some wrestling with alignment)
I just want to be able to take a value and put it into a suitable size buffer, and vice versa.

The best I've found is that I can write any value into memory using @memcpy(buf, mem.asBytes(&value)); //&@as([@sizeOf(T)]u8, @bitCast(value))); (not worried about endianness I know I'm gonna be on LE)

#

well, immediately after writing that I found something that worked...

fn decode_T (comptime T: type, buf:[*]u8) T {
  var b :[@sizeOf(T)]u8=undefined;  
  @memcpy(b[0..@sizeOf(T)], buf[0..@sizeOf(T)]);
  return @bitCast(b);
}

I only got here by trying random things until something worked so I don't really know why zig allows this but not everything else that I tried

true rivet
#

another way to do that with endianness

return std.mem.readInt(T, buf[0..@sizeOf(T)], .little);
#

ah finally noticed your comment about endianness. here's another way to do that. basically the same thing bit a little shorter:

    return @bitCast(buf[0..@sizeOf(T)].*);
#

the reason this works is that slicing with comptime known bounds creates an array pointer (*[N]u8) instead of a slice.

#

you can also do the same thing with a runtime offset:

buf[i..][0..@sizeOf(T)]