上下文
我目前正在研究一个探测气球。我的通信仅限于12个字节的消息,其中我必须发送几个信息。(海拔,最高气温,经度,纬度,平均加速度)。
该探针基于树莓π2b。
问题
我目前正在构建我的数据报,并希望将我的纬度和经度存储为32位双(有损)。存储可以用浮点,也可以用固定点,有工具可以做这种转换吗?我还能怎么做呢?(特别是在圆角方)
我最初计划用Java工作,但我可以迁移到python。
提前谢谢你
发布于 2018-07-11 20:54:45
如果要将double
转换为64位,可以使用long Double.doubleToLongBits(double value)
和double Double.longBitsToDouble(long bits)
将其转换回来。
如果要将32位值转换为Float
值并返回,则对应的函数是floatToIntBits(...)
和intBitsToFloat(...)
。
对于double
到32位,我将使用2步转换,首先转换为float
:
double val = ...;
int bits = Float.floatToIntBits( (float) val );
然后回来:
int bits = ...;
double val = (double) Float.intBitsToFloat(bits);
直接包装和解压到缓冲器:
ByteArrayOutputStream baos = new ByteArrayOutputStream(20);
DataOutputStream dos = new DataOutputStream( ... );
dos.writeFloat( altitude );
dos.writeFloat( max_temperature );
dos.writeFloat( longitude );
dos.writeFloat( latitude );
dos.writeFloat( average_acceleration);
byte[] data = baos.toByteArray();
当然,这会创建一个20字节的缓冲区(5x32位浮动),而不是一个12字节的缓冲区,因此您需要知道哪些值是32位,哪些值可以塞进更小的空间。
打开包装,使用DataInputStream
和readFloat()
。
ByteArrayInputStream bais = ...
DataInputStream dis = new DataInputStream(bais);
altitude = dis.readFloat();
max_temperature = dis.readFloat();
...etc...
发布于 2018-07-11 20:55:49
我建议使用一个分数,而不是真正为lat/long设计的float
。如果您乘以Integer.MAX_VALUE/90
表示纬度,Integer.MAX_VALUE/180.0
乘以经度,您将得到一个更有效地使用32位值的值。
float lat = 90f;
System.out.println("precision using float: " + (lat - Math.nextDown(lat)) + " degrees");
double ratio = Integer.MAX_VALUE / 90.0;
int val2 = (int) Math.round(90 * ratio);
System.out.println("precision using int: " + 1 / ratio + " degrees");
版画
precision using float: 7.6293945E-6 degrees
precision using int: 4.190951587721217E-8 degrees
简而言之,一个int
可以拥有超过100倍的精度,因为它有32位的精度,而float
有一个23位的尾数。
对于经度,此误差表示浮点数为1.7m,使用int
表示0.94cm。
注意:如果2m错误是可以的(比移动电话GPS更准确),您可能会认为float
更容易处理。
https://stackoverflow.com/questions/51293429
复制相似问题