Я использую JRI и хочу получить числовое значение от R как примитивное долгое время в java. Класс org.rosuda.REngine.REXP предоставляет только методы asDouble() и asInteger(). Оба не работают должным образом. Кажется, это проблема переполнения.Получение длинного значения от R до java
Существует два модульных теста: первый использует метод asDouble(), второй использует asString() (и может быть расширен для использования BigInteger.longValue()).
@Test
public final void testWithDouble() throws Exception {
REngine engine;
engine = REngine.engineForClass("org.rosuda.REngine.JRI.JRIEngine");
engine.parseAndEval("rm(list=ls(all=TRUE))");
engine.assign("a", new int[] { 100000 });
engine.parseAndEval("b <- a * a");
REXP exp = engine.parseAndEval("b", null, true);
double b = exp.asDouble();
System.out.println(b); // prints -2.147483648E9
Assert.assertEquals(1e10, b, 1.0);
}
@Test
public final void testWithBigInteger() throws Exception {
REngine engine;
engine = REngine.engineForClass("org.rosuda.REngine.JRI.JRIEngine");
engine.parseAndEval("rm(list=ls(all=TRUE))");
engine.assign("a", new int[] { 100000 });
engine.parseAndEval("b <- a * a");
REXP exp = engine.parseAndEval("options(scipen=99); toString(b)", null, true);
String b = exp.asString();
System.out.println(b); // prints "NA"
Assert.assertEquals("10000000000", b);
// Now, this can be used to create a BigInteger and then the method longValue() helps.
}
Существует следующий раздел в моем pom.xml:
<dependency>
<groupId>com.github.lucarosellini.rJava</groupId>
<artifactId>JRIEngine</artifactId>
<version>0.9-7</version>
</dependency>
Может кто-нибудь помочь мне получить правильную долгосрочную ценность?
UPDATE 2016-03-17
Я добавил новую версию REngine в pom.xml. Для артефактов JRIEngine и JRI я не нашел более новую версию, чем 0.9-7.
<dependency>
<groupId>org.rosuda.REngine</groupId>
<artifactId>REngine</artifactId>
<version>2.1.0</version>
</dependency>
Проблемы такие же.
Отладка testWithDouble()
показывает, что нативный метод возвращает rniExpType(long)
INTSXP
, а затем нативный метод rniGetIntArray(long)
называется. Я думаю, что этот последний вызов вызывает переполнение.
Действительно, нет такого типа данных, как long ... После смены назначения (String, int []) для назначения (String, double []) все работает нормально. –