Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将double转换为32位表示(和反向过程)_Java_Precision_Iot_Data Conversion - Fatal编程技术网

Java 将double转换为32位表示(和反向过程)

Java 将double转换为32位表示(和反向过程),java,precision,iot,data-conversion,Java,Precision,Iot,Data Conversion,[Context] 我目前正在研制一个探测气球。我的通信被限制在12字节的消息中,我必须在其中传输几条信息。(高度、最高温度、经度、纬度、平均加速度)。 该探针基于树莓皮2 b [问题] 我目前正在构建数据报,希望将纬度和经度存储为32位双精度(有损)。可以使用浮点或定点进行存储 有没有工具可以进行这种转换?我还能怎么做呢?(特别是在四舍五入的一方) 我最初计划使用Java,但我可以迁移到python 提前谢谢如果要将双精度转换为64位,可以使用,并将其转换回 如果要将32位值转换为值并返回,相

[Context]
我目前正在研制一个探测气球。我的通信被限制在12字节的消息中,我必须在其中传输几条信息。(高度、最高温度、经度、纬度、平均加速度)。
该探针基于树莓皮2 b

[问题]
我目前正在构建数据报,希望将纬度和经度存储为32位双精度(有损)。可以使用浮点或定点进行存储 有没有工具可以进行这种转换?我还能怎么做呢?(特别是在四舍五入的一方)
我最初计划使用Java,但我可以迁移到python


提前谢谢

如果要将
双精度
转换为64位,可以使用,并将其转换回

如果要将32位值转换为值并返回,相应的函数是
floatToIntBits(…)
intBitsToFloat(…)

对于
double
到32位,我将使用两步转换,首先转换为
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字节的缓冲区(5 x 32位浮动),而不是12字节的缓冲区,因此您需要确定哪些值需要作为32位,哪些值可以填充到更小的空间中

解包时,使用
DataInputStream
readFloat()


我建议使用分数,而不是真正为lat/long设计的
float
。如果将纬度乘以
Integer.MAX_值/90
,将经度乘以
Integer.MAX_值/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
更易于处理。

您的位置API为您的程序提供了哪些数据?它使用整数还是浮点?什么坐标系?什么数据?你的问题相当抽象,所以我能给出的最具体的建议是取你所在位置的模数;您不需要牺牲精度,因为对于从已知点开始的不断变化的位置,您应该能够猜测高阶组件。您对精度有任何最低要求或范围有任何最大限制吗?显然,这是一种权衡;如果您需要能够在全球范围内对任何纬度/经度进行编码,您的最佳精度将是纬度65536/180(约35公里),经度65536/360(约70公里)。我还应该提到,仅传输位置之间的增量将提供大量“压缩”,但我假设您的简单传输协议不可靠,因为丢失的数据包将被重新发送,因此随着时间的推移,随着更多数据包丢失,气球位置的不确定性将增加。所以我建议传输绝对位置。尽管如此,我想一种混合的方法,在低频段发送绝对位置,在高频段发送增量,可能会很好。你怎么能有一个32位的双精度?Double表示与单精度浮点相比的双精度。double是64位的,singles或float是32位的。另外,我应该问:你所有的数据包都必须是相同的吗?为什么不发送多个数据包来携带您想要的所有信息呢?
MAX_VALUE/90.0
对于纬度来说可以,但是经度从-180到+180,所以您应该使用
MAX_VALUE/180.0
来表示经度。您也可以将其用于纬度和一致性,但会损失1位精度。@AJNeufeld很好。需要不同的经度比率。
precision using float: 7.6293945E-6 degrees
precision using int: 4.190951587721217E-8 degrees