【问题标题】:Java Bitwise AND operation between a double and int value [closed]双精度值和整数值之间的Java按位与运算[关闭]
【发布时间】:2012-12-18 07:26:08
【问题描述】:

我有一个纬度值作为双精度值,我想对其执行按位与运算,然后进行位右移。以下是我的代码行:

pBuffer[1]=(latitude_decimal_degrees & 0xFF0000) >> 16;

然而,双精度值和整数值之间的位与运算是不可能的。我无法将纬度转换为 int,因为这不会产生准确的值。有人可以指导我吗?

编辑:我的要求基本上是将以下 vb.net 代码翻译成 java。原因:下面的代码行 (vb.net) 是用“Basic4Android”编写的用于 android 应用程序的方法的一部分。完全相同的方法将在我的 BlackBerry App 中实现。因此,我需要生成与下面完全相同的值,该值将在服务器端进行解码:

Dim pBuffer(11) As Int
Dim longitude_decimal_degrees As Double
pBuffer(1)=Bit.ShiftRight(Bit.And(latitude_decimal_degrees, 0xFF0000),16)

这几行代码怎么翻译成java?

【问题讨论】:

  • 如果你描述你想要完成的事情会更好,而不是你认为你将如何完成它。
  • 这看起来确实像an XY Problem
  • @Perception 是对的:你实际上想做什么?这是不可能的,因为它没有意义。我们没有得到你想要的东西,应该怎么编译?你是否例如想得到双纬的整数部分?然后使用roundfloor
  • 如果您的latitudedouble 值,并且可以将AND 设置为0xFF0000,您基本上会丢失所有信息并且无法取回它。你知道吗?你能描述一下服务器预期的格式吗?
  • 归根结底,所有数据都是二进制的。我不知道您所说的十六进制编码是什么意思。二进制和十六进制是表示数字的系统。因此,每个二进制数都可以转换为十六进制数。但是,即使是十六进制数,也可以在任何计算机上以二进制形式存储。我们知道您有 latitude 作为 double 值,但为了让我们帮助您,我们需要有关您将其转换为的格式的更多详细信息。

标签: java vb.net bit-manipulation bit-shift


【解决方案1】:

您可以使用Double.doubleToRawLongBits(latitude_decimal_degrees) 将双精度通过位转换为长空间,在长空间中执行所有按位运算,然后通过 longBitsToDouble 转换回双精度

另请参阅此 SO 答案:https://stackoverflow.com/a/4211117/504685

【讨论】:

  • 哪个更准确;将 double 转换为 int(我已经用尝试的解决方案编辑了我的问题)或将其转换为 long,请提出建议。
  • 转换为 long 会更“准确”,因为 double 和 long 都是 64 位。将 double 转换为 int 会导致精度损失(64 -> 32 位)。有关原始大小的更多信息,请参阅:docs.oracle.com/javase/tutorial/java/nutsandbolts/…
  • 感谢您的链接。我无法对 double 或 long 值执行位移。我该如何处理?在 AND 操作之后,我需要右移 16 位。
  • @Sarah 你需要解决的问题是:之后你打算做什么?你想以某种方式解码数据吗?否则,你还不如发送随机数据...
  • @Anony-Mousse 是的,当然我会解码数据。请参阅我们在此处遵循的固定格式。该应用程序将在 Android 和 BlackBerry 上开发。我正在做黑莓应用程序。提供给我们的消息格式和方法,我们必须严格遵守。我有用“Basic4Android”编写的 vb.net 代码。我看到了其中的逻辑,并在 BlackBerry 的 java 中编写了相同的逻辑。要求是在两个变量之间执行 AND 操作,然后对结果应用右位移。服务器将进行解码。我必须以这种格式发送数据。
【解决方案2】:

正如您自己和其他人所指出的,不可能对浮点数执行位移。现在,根据您更新的问题,您正在使用一个自定义库,该库实现了自己的位运算符版本。这些运算符的所有操作数都转换为 int 的

ShiftRight (N As Int, Shift As Int) As Int
And (N1 As Int, N2 As Int) As Int

为了匹配此逻辑,您的 Java 代码还应在执行必要的位操作之前将其 double 值转换为 int:

double latitude = 52.5233;
int transform = (((int)latitude) & 0xFF000000) >> 16;

请注意,这假设 Basic4Android 遵循与 Java 相同的从 int 到 double 的转换规则(数字向下舍入为整数)。

当您完成移植代码后,通过它传递一组值,并确保您的 Basic4Android 和 Java 代码中的最终结果相同。

【讨论】:

  • 感谢您抽出宝贵时间调查此问题。我从一开始就怀疑将纬度转换为 int 会产生不正确的结果,因为我们失去了纬度值所需的准确性。这是正确的吗? 52.5233 的双精度值将更改为 int 52。是这样吗?请确认。
  • 老实说,我现在看不出这段代码在 Android 端是如何工作的。到处都在丢失信息。向下转换为 int 可能会截断双精度值,并且至少会丢失小数部分。 and 运算符从现在截断的 int 的高位中选择一个字节,对于大多数纬度而言,该字节为零。然后将该零移动 16 位以再次产生零。你说这是来自工作程序的代码?
  • 是的,此代码适用于 android 和 iphone。它最初是为安卓应用程序开发的。同样已在 iphone 应用程序中成功实施。我现在在 BlackBerry 应用程序中应用相同的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多