2012-04-07 32 views
5

Tôi đang triển khai thực hiện BigInt nhanh hơn và tôi không chắc chắn về cách tôi nên đi để cung cấp interop với nền tảng cơ bản.Tôi gặp phải vấn đề gì khi sử dụng Reflection để giao tiếp với java.math.BigInteger?

Hôm nay BigInt chỉ kết thúc tốt đẹp một BigInteger và giá trị bigInteger chỉ trả về giá trị gói:

class BigInt(val bigInteger: BigInteger) ... 

Bởi vì tôi không gói một loại Java, tôi sẽ phải làm một cái gì đó giống như

final class BigInt private(final val signum: Int, 
          final private[math] val arr: Array[Int]) 
    def bigInteger: java.math.BigInteger = { 
    // Avoid copying of potentially large arrays. 
    val ctor = classOf[java.math.BigInteger] 
       .getDeclaredConstructor(classOf[Array[Int]], classOf[Int]) 
    ctor setAccessible true 
    ctor.newInstance(arr, signum.asInstanceOf[Object]) 
    } 
... 
} 

Điều này có gây ra rắc rối hoặc có cách nào tốt hơn để làm điều đó không?

+0

Tôi không biết số lượng lớn, nhưng sao chép một mảng nhỏ của int có thể nhanh hơn so với sử dụng sự phản chiếu ... – paradigmatic

+0

Vâng, chắc chắn. Nó không quan trọng đối với mảng nhỏ, nhưng kích thước của các con số chỉ bị giới hạn bởi RAM. Tôi chỉ không muốn ăn bộ nhớ khi chuyển dữ liệu từ cấu trúc dữ liệu bất biến sang cấu trúc dữ liệu khác. – soc

+0

Số nguyên tử trong toàn bộ vũ trụ thường được ước tính là 10^80. Chỉ với 9 * 32 bit, bạn có thể chỉ định một chỉ mục duy nhất cho mỗi chỉ mục. Tôi tin tưởng mạnh mẽ rằng nếu bạn cần một con số tự nhiên lớn hơn, đó có thể là lỗi hoặc lỗi thiết kế ... – paradigmatic

Trả lời

3

Nói chung khi tôi đã nhìn thấy người sử dụng nhà thầu hoặc các phương pháp tư nhân (hoặc không có giấy tờ) như thế này, họ bắt NoSuchMethodException và cung cấp một sự lựa chọn:

object BigInt { 
    import java.math.BigInteger 

    private val toBigInteger: (Array[Int], Int) => BigInteger = try { 
    val ctor = classOf[BigInteger].getDeclaredConstructor(
     classOf[Array[Int]], classOf[Int] 
    ) 
    ctor.setAccessible(true) 

    (arr, signum) => ctor.newInstance(arr, signum.asInstanceOf[Object]) 
    } catch { case _: NoSuchMethodException => 
    (arr, signum) => 
     val buffer = java.nio.ByteBuffer.allocate(arr.length * 4) 
     buffer.asIntBuffer.put(arr) 
     new BigInteger(signum, buffer.array) 
    } 
} 

final class BigInt(final val signum: Int, final val arr: Array[Int]) { 
    def bigInteger = BigInt.toBigInteger(arr, signum) 
} 

Tôi cũng đã chuyển các doanh nghiệp phản ánh tắt để một đối tượng đồng hành để tránh phải trả hầu hết số tiền đó mỗi khi bạn gọi bigInteger.

+0

Cách tiếp cận thú vị, cảm ơn! – soc

+0

Tôi sẽ không phải tìm kiếm 'SecurityException' thay vì 'NoSuchMethodException'? Điều thú vị là JavaDoc thậm chí đề cập đến constructor này là công khai, vì vậy tôi không nghĩ rằng nó sẽ biến mất. – soc

Các vấn đề liên quan