C аппроксимационные функции - PullRequest
0 голосов
/ 10 сентября 2010

Я делаю некоторые функции приближения для exp, log и sqrt в C для Java. Я немного расстроен тем, как работают указатели - правильна ли эта грамматика?

#include <math.h>
#include "QDMath.h"

JNIEXPORT jdouble JNICALL Java_QDMath_exp
  (JNIEnv *env, jclass class, jdouble val)
{
    jint tmp = (jint) (1512775 * val + 1072632447);
    jdouble p = 0.0;
    *(1 + (jint * ) &p) = tmp;
    return p;
}

JNIEXPORT jdouble JNICALL Java_QDMath_log
  (JNIEnv *env, jclass class, jdouble val)
{
    jint tmp = (*(1 + (jint *) &val));
    jdouble p = ((jdouble) tmp - 1072632447) / 1512775;
    return p;
}

JNIEXPORT jdouble JNICALL Java_QDMath_sqrt
  (JNIEnv *env, jclass class, jdouble val)
{
    jlong tmp = ((*(jlong *) &val) - 1065353216)>>1;
    return *(jdouble *) &tmp;
}

Ответы [ 2 ]

5 голосов
/ 10 сентября 2010

На первый взгляд, синтаксис выглядит правильным (хотя компилятор скажет вам быстрее, чем мы).

Однако то, что вы делаете с ними, выглядит довольно мрачно. Переинтерпретация double s как int s зависит от платформы (подумайте о порядке байтов и sizeof), а также нарушит правила "строгого алиасинга".

2 голосов
/ 10 сентября 2010

В общем, это выглядит очень неправильно и подняло некоторые красные флажки для меня, но вы можете быть в порядке.

Использование типов Java помогает. Если вы выполняете приведение к int, у вас могут возникнуть проблемы на некоторых машинах, поскольку ints может быть 32-разрядным или 64-разрядным. Используя jint, он всегда должен быть 32-битным, поэтому в этом отношении вы в безопасности.

Мне все еще не совсем понятно, что вы пытаетесь сделать. Например, эта строка:

*(1 + (jint * ) &p) = tmp;

То, что вы говорите, это взять адрес p (двойной), обработать его как целочисленный адрес Java, а затем добавить его к нему. Это означало бы взять местоположение двойного и посмотреть 4 байта в нем ... поместить вас куда-то в дробную часть IEEE-кодированного двойного .

Затем вы устанавливаете это местоположение в значение tmp ..., которое является целым числом, а не IEEE-кодированием.

Если вы не делаете что-то невероятно умное , непосредственно манипулируя битами двойника, то, что вы делаете, приведет к бессмысленным результатам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...