Java вычисляет неверные результаты - PullRequest
0 голосов
/ 18 июля 2011

Я пытаюсь определить знак числа для последующего расчета.

У меня есть код, подобный следующему:

double value = someClass.someGetterMethod();
double sign = value / Math.abs(value);

Я также пробовал:

double sign = (value < 0) ? -1d : 1d;

Не всегда, но иногда значение положительное, а знак отрицательный.

Обе переменные находятся в локальном стеке в нестатическом методе, поэтому я не верю, что есть условие гонки.

К сожалению, я не могу выпустить полный исходный код, и я не смог воспроизвести это в меньшем примере. Я подозреваю, что мое окружение как-то связано с этим:

Соответствующий код упакован в jar-файл, который затем загружается в виде zipgroupfileset в файл jar плагина, который загружается netLogo как «расширение» (плагин). Итак, запущен NetLogo, который загружает плагин jar, содержащий класс с этим кодом.

NetLogo требует, чтобы все плагины должны были быть скомпилированы для цели 1.5, поэтому у меня есть этот набор для lib и расширения в моих файлах сборки ant.

Я подключаю свой отладчик netbeans, изменяя netlogo vmargs, чтобы разрешить удаленную отладку

-Xdebug
-Xrunjdwp:transport=dt_socket,address=1000,server=y,suspend=n

Я действительно в тупике. Это проблема с тем, как отладчик отображает переменные? Может быть, проблема с целевым требованием компиляции NetLogo 1.5?

Есть идеи?

Спасибо

Ответы [ 3 ]

1 голос
/ 18 июля 2011

Это действительно может быть проблема с отображением, поскольку я не понимаю, каким образом рассматриваемый код может иметь поведение, которое вы описываете.

Если бы я устранял это, я бы сделал переменные final и вычислил бы sign сразу после value:

final double value = someClass.someGetterMethod();
final double sign = (value < 0) ? -1d : 1d;

Наконец, я бы вывел обе переменные сразу после присвоения sign. Если, сделав все это, вы можете запустить печать value и sign с непоследовательными знаками, то что-то серьезно, серьезно неправильно.

P.S. Я призываю вас рассмотреть возможность перехода на Math.signum. Вероятно, это не решит вашу текущую проблему, но будет обрабатывать нули и NaN более изящно.

1 голос
/ 18 июля 2011

Решение, которое должно позволить вам устранить всю неоднозначность, состояло бы в преобразовании значения в необработанный длинный и проверки значения подписанного бита:

long rawValue = Double.doubleToRawLongBits(value);
boolean isNegative = (rawValue & 0x8000000000000000L) != 0;
0 голосов
/ 18 июля 2011

Почему знак двойной?будет ли работать INT для вас?

Ваш первый способ вычисления знака может быть подвержен ошибкам округления из-за характера чисел с плавающей запятой / двойных чисел.Я бы сказал, пойти вторым путем:

double value = someClass.someGetterMethod();
int  sign = (value < 0) ? -1 : 1;

Может быть, это даст вам лучшие результаты.

...