2016-03-14 10 views
1

Я использую 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) называется. Я думаю, что этот последний вызов вызывает переполнение.

ответ

2

Ваши тесты не тестируют ничего близкого к тому, что вы описываете, long вообще не участвует. Вы просто передаете NA_integer_ из R в Java, потому что добавление переполняет 32-разрядные целые числа с предупреждением в R. Вы можете проверить это с помощью метода isNA(). Если вы хотите избежать переполнения в арифметике, используйте числовой тип в R.

+0

Действительно, нет такого типа данных, как long ... После смены назначения (String, int []) для назначения (String, double []) все работает нормально. –

 Смежные вопросы

  • Нет связанных вопросов^_^