2008-10-07 75 views
64

Hiện tại tôi là borrowing java.math.BigInteger from the J# libraries as described here. Chưa bao giờ sử dụng một thư viện để làm việc với số nguyên lớn trước đây, điều này có vẻ chậm, theo thứ tự chậm hơn 10 lần, ngay cả đối với số chiều dài ulong. Có ai có bất kỳ tốt hơn (tốt nhất là miễn phí) thư viện, hoặc là mức độ hiệu suất bình thường?Số nguyên lớn trong C#

+0

đẹp liên kết. Một vài đá quý ở đó. –

+3

Chỉ có vấn đề là họ yêu cầu cài đặt lại Red # J #. Thực tế là J # là tất cả nhưng đã chết (nó không phải là trong VS 2008 atleast) có lẽ không giúp thúc đẩy điều đó. –

+0

J # chỉ để tạo thuận lợi cho việc di chuyển các dự án Java hiện có sang .NET. Tôi chắc chắn sẽ không kết hợp bất kỳ thư viện nào của nó vào một dự án mới. – MusiGenesis

Trả lời

63

Kể từ .NET 4.0, bạn có thể sử dụng lớp System.Numerics.BigInteger. Xem tài liệu tại đây: http://msdn.microsoft.com/en-us/library/system.numerics.biginteger(v=vs.110).aspx

Một giải pháp thay thế khác là lớp học IntX.

IntX là một độ chính xác số nguyên tùy ý thư viện viết bằng C# thuần túy 2.0 với nhanh - O (N * log N) - nhân/thuật toán phân chia thực hiện. Nó cung cấp tất cả các thao tác cơ bản trên số nguyên như Ngoài ra, nhân, so sánh, Bitwise chuyển, vv

+26

Đối với bản ghi, cụm từ 'System.Numerics' không được tham chiếu theo mặc định trong các dự án mới, do đó, điều này cần phải được thêm trước khi' BigInteger' có thể được sử dụng. –

+0

Trong Solution Explorer, nhấp chuột phải vào Tham khảo> Thêm tham chiếu> Tìm kiếm số và kiểm tra tham chiếu đã tìm thấy. Bây giờ bạn có thể thêm "using System.Numerics;" ở đầu tệp .cs – Jan

3

Tôi không chắc chắn về hiệu suất, nhưng IronPython cũng có một lớp BigInteger. Nó nằm trong không gian tên Microsoft.Scripting.Math.

2

Có, nó sẽ chậm và chênh lệch 10x là về những gì tôi mong đợi. BigInt sử dụng một mảng để biểu thị độ dài tùy ý và tất cả các thao tác phải được thực hiện thủ công (trái ngược với hầu hết toán học có thể được thực hiện trực tiếp với CPU)

Tôi thậm chí không biết mã hóa bằng tay hay không lắp ráp sẽ cung cấp cho bạn nhiều hiệu suất đạt được trên 10x, đó là khá damn gần. Tôi sẽ tìm những cách khác để tối ưu hóa nó - đôi khi tùy thuộc vào vấn đề toán học của bạn có rất ít thủ thuật bạn có thể làm để làm cho nó nhanh hơn.

2

Tôi đã sử dụng Biginteger ở công việc trước đó. Tôi không biết bạn cần loại hiệu suất nào. Tôi đã không sử dụng nó trong một tình huống thực hiện chuyên sâu, nhưng không bao giờ có bất kỳ vấn đề với nó.

2

Điều này có vẻ giống như một đề xuất lạ, nhưng bạn đã thử nghiệm loại decimal để xem tốc độ hoạt động của nó chưa?

Phạm vi thập phân là ± 1,0 × 10^−28 đến ± 7,9 × 10^28, do đó, nó vẫn có thể không đủ lớn, nhưng nó lớn hơn một ulong.

Có nghĩa vụ phải là lớp BigInteger trong .NET 3.5, nhưng it got cut.

+0

Vâng, tôi thấy rằng một sự tuyên bố khi ban đầu tìm kiếm một thư viện BigInt. Làm tôi buồn. Oh well. –

+0

Bạn sẽ phải cẩn thận - bằng cách sử dụng một số thập phân có thể gây ra các vấn đề làm tròn. – Blorgbeard

+0

Thập phân không gây ra lỗi làm tròn. Nó không phải là điểm nổi. – Kibbee

4

Tôi nghĩ bạn có thể tối ưu hóa việc triển khai nếu bạn thực hiện tất cả các thao tác trên BigInts sẽ trả lại kết quả nhỏ hơn kiểu gốc (Ví dụ: int64) trên các kiểu gốc và chỉ xử lý mảng lớn nếu bạn định tràn.

chỉnh sửa implementation on codeproject này, dường như chậm hơn chỉ 7 lần ... Nhưng với sự tối ưu hóa ở trên, bạn có thể nhận được nó để thực hiện gần như giống hệt với các loại bản địa cho số lượng nhỏ.

+0

Tôi tin rằng thư viện J # sử dụng nội bộ của Byte, nó có một hàm ToByteArray() ít nhất, và không có hàm ToArray() khác. Điều này có thể là một ý tưởng nếu tôi muốn cuộn của riêng tôi, tôi không quá vui mừng với ý tưởng đó hoặc là mặc dù. –

+0

Bạn đang làm việc với dữ liệu kích thước nào? Công cụ sẽ tràn kích thước Int64 một cách thường xuyên, hay nó là một ngoại lệ? –

+0

Tôi đang làm nó chủ yếu trên cơ sở từng trường hợp, thiết lập nó thành BigInt khi tôi chạy vào một tràn với một khối {} đã kiểm tra. Nếu nó làm điều đó một lần, sau đó có một cơ hội khá tốt nó sẽ làm điều đó nhiều lần và thường xuyên. –

1

Điều này sẽ không giúp bạn, nhưng có nghĩa vụ phải là một lớp BigInteger trong .Net 3.5; nó đã bị cắt, nhưng từ các báo cáo được thực hiện tại PDC, nó sẽ có trong .Net 4.0. Họ dường như đã dành rất nhiều thời gian để tối ưu hóa nó, vì vậy hiệu suất sẽ tốt hơn nhiều so với những gì bạn đang nhận được ngay bây giờ.

Hơn nữa, câu hỏi này về cơ bản là một bản sao của How can I represent a very large integer in .NET?

+0

BigInteger là trong 3,5 nhưng nó là một lớp nội bộ.) Của nó có chỉ là không sẵn sàng cho thời gian đầu. –

1

Xem câu trả lời trong thread này. Bạn sẽ cần phải sử dụng một trong các thư viện/các số nguyên lớn của bên thứ ba có sẵn hoặc chờ C# 4.0 sẽ bao gồm một kiểu dữ liệu BigInteger gốc.

9

F# cũng giao hàng với một. Bạn có thể lấy nó tại Microsoft.FSharp.Math.

8

Lớp System.Numerics.BigInteger trong .NET 4.0 được dựa trên Microsoft.SolverFoundation.Common.BigInteger từ Microsoft Research.

Lớp Anver của BigInteger lớp trông rất có hiệu suất. Tôi không chắc chắn về giấy phép mà nó được phát hành theo, nhưng bạn có thể nhận được nó here (tải xuống và cài đặt Solver Foundation và tìm Microsoft.Solver.Foundation.dll).

4

Dưới đây là một số triển khai của BigInteger trong C#. Tôi đã sử dụng thực hiện BigInteger Mono của, hoạt động khá nhanh (Tôi đã sử dụng nó trong CompactFramework)

Bouncy Castle

Mono

1

này Trông rất hứa hẹn. Đây là Trình bao bọc C# trên GMP.

http://web.rememberingemil.org/Projects/GnuMpDotNet/GnuMpDotNet.html

Ngoài ra còn có tùy chọn BigInteger khác cho Net here nói riêng, Mpir.Net

+1

Mpir.NET một phần dựa trên wrapper GMP của Emil. Một phần khác là X-MPIR, và hợp nhất với nhau, bạn sẽ có được sự tiện lợi của trình bao bọc của Emil và hiệu suất của X-MPIR. –