我想确定一个数字的符号,以便在以后的计算中使用。
我有类似下面的代码:
double value = someClass.someGetterMethod();
double sign = value / Math.abs(value);
我也试过了:
double sign = (value < 0) ? -1d : 1d;
不总是,但有时value为正,sign为负。
在非静态方法中,两个变量都在本地堆栈上,所以我认为不存在竞争条件。
不幸的是,我无法发布完整的源代码,也无法在一个较小的示例中复制这一点。我怀疑这与我的环境有关:
所讨论的代码被打包到一个jar中,然后作为zipgroupfileset加载到一个插件jar文件中,该文件由netLogo作为"扩展"(插件)加载。于是NetLogo启动了,它加载了包含这个类的插件jar。
NetLogo要求任何插件都需要为1.5目标编译,所以我在ant构建文件中为库和扩展设置了这个设置。
我通过修改netlogo vmargs来连接netbeans调试器,以允许远程调试
-Xdebug
-Xrunjdwp:transport=dt_socket,address=1000,server=y,suspend=n
我真的难住了。这是调试器如何显示变量的问题吗?也许是NetLogo的1.5编译目标要求有问题?
任何想法?
谢谢
这确实可能是一个显示问题,因为我不明白有问题的代码如何具有您描述的行为。
如果我要解决这个问题,我会让变量final
,并在value
之后计算sign
:
final double value = someClass.someGetterMethod();
final double sign = (value < 0) ? -1d : 1d;
最后,我将在赋值给sign
之后打印两个变量。如果在完成所有这些操作后,您可以触发具有不一致符号的value
和sign
的打印,那么一定有严重、严重的错误。
注:我强烈建议您考虑切换到Math.signum
。它可能不会解决您当前的问题,但它会更优雅地处理零和nan。
消除所有歧义的解决方案是将值转换为原始长并检查带符号位的值:
long rawValue = Double.doubleToRawLongBits(value);
boolean isNegative = (rawValue & 0x8000000000000000L) != 0;
为什么sign是double?你觉得这样行吗?
由于浮点数/双精度数的性质,计算符号的第一种方法可能容易产生舍入误差。我会说选择第二种方式:
double value = someClass.someGetterMethod();
int sign = (value < 0) ? -1 : 1;