81

I need to do some large integer math. Are there any classes or structs out there that represent a 128-bit integer and implement all of the usual operators?

BTW, I realize that decimal can be used to represent a 96-bit int.

phuclv
  • 37,963
  • 15
  • 156
  • 475
Adam Tegen
  • 25,378
  • 33
  • 125
  • 153
  • 2
    Out of curiosity, why do you need to work with such large numbers? – Jason Kleban May 13 '10 at 16:59
  • 35
    Note that a native unsigned int128 would be a natural representation of an IPv6 address, adding to urgency and relevance of this question – Martijn Apr 03 '12 at 11:16
  • There's a question in C++ that does discuss this in more detail, specifically how to simulate Int128 addition and subtraction http://stackoverflow.com/a/741371/58961 – John Leidegren Jun 12 '13 at 08:10
  • 1
    Int128 and UInt128 will be in .NET 7 (see https://devblogs.microsoft.com/dotnet/dotnet-7-generic-math/#types-without-language-support and https://github.com/dotnet/runtime/issues/67151) – ckuri Jun 11 '22 at 12:35

9 Answers9

58

While BigInteger is the best solution for most applications, if you have performance critical numerical computations, you can use the complete Int128 and UInt128 implementations in my Dirichlet.Numerics library. These types are useful if Int64 and UInt64 are too small but BigInteger is too slow.

Rick Sladkey
  • 33,988
  • 6
  • 71
  • 95
  • 2
    This most accurately answers the question, and in a very helpful way. – Timo Nov 07 '17 at 15:05
  • Your uint128 has four ulong fields causing it to use 32 bytes. Why does it need the two extra ulong? – jjxtra Apr 09 '19 at 21:21
  • 3
    No, it has two ulong fields. Certain operations (such as modular multiplication) require 256 bit accuracy for intermediate results, so a representation for UInt256 is also necessary. That private type does indeed (and must have) have four ulong fields. – Rick Sladkey Apr 11 '19 at 16:21
  • I'm not used to that coding style so just to make sure, did you write just like in C++ by using `ref` and `out` to avoid `pass-by-value` allocations since `UInt128` is a struct ? Very nice library btw. – Lorenzo Nov 13 '21 at 22:11
  • very poor, naive and slow implementation – MrUnbelievable92 Oct 21 '22 at 07:34
57

It's here in System.Numerics. "The BigInteger type is an immutable type that represents an arbitrarily large integer whose value in theory has no upper or lower bounds."

var i = System.Numerics.BigInteger.Parse("10000000000000000000000000000000");
phuclv
  • 37,963
  • 15
  • 156
  • 475
Larsenal
  • 49,878
  • 43
  • 152
  • 220
  • 62
    Okay, so a BigInteger satisfies that need but it's not a Int128 type, it does heap allocations (a lot of 'em, per operation) and operates on 32-bit words, there's overhead in something like that and while it supports an arbitrary range, I wouldn't use that if I knew I really needed an Int128 type. I reckon people have been using smaller sized integers to simulate a larger sized integer for some time (due to various hardware restrictions) and it shouldn't be to hard to find the appropriate C code and adapt that. My point is, BigInteger is a solution to the general case, not Int128 specifically. – John Leidegren Jun 12 '13 at 08:07
  • 1
    FYI: BigInteger is not available for .NET 2 – Thomas Weller Sep 24 '14 at 20:08
  • 23
    BigInteger ≠ Int128 – markshep Aug 15 '16 at 10:27
  • use two qwords (`long`) instead of biginteger if you are after performance. – M.kazem Akhgary May 09 '17 at 06:06
23

System.Int128 and System.UInt128 have been available since .NET Core 7.0 Preview 5

They were implemented in Add support for Int128 and UInt128 data types

I don't know why they aren't in the .NET 7 Preview 5 announcement but in the upcoming .NET 7 Preview 6 announcement there'll also be Int128Converter and UInt128Converter for the new types in Preview 5

They didn't have C# support yet though, just like System.Half, so you'll have to use Int128 explicitly instead of using a native C# keyword

phuclv
  • 37,963
  • 15
  • 156
  • 475
  • how would **you** name int128 ? Huge? ;) what would be int256 then ?? :)) – Boppity Bop Jan 30 '23 at 17:56
  • @BoppityBop `llong`, which is kind of common in various libraries. `extended` is also common in C. Or look at delphi with [its silly names like `Cardinal`](https://stackoverflow.com/a/63156176/995714) – phuclv Feb 01 '23 at 10:43
15

No, there's nothing in .NET <= 3.5. I'm hoping/expecting that BigInteger will make its return in .NET 4.0. (It was cut from .NET 3.5.)

phuclv
  • 37,963
  • 15
  • 156
  • 475
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 5
    It was actually [reintroduced in .NET 4.0](http://msdn.microsoft.com/en-us/library/system.numerics.biginteger(v=vs.110).aspx) and is still around. – Drew Noakes Aug 26 '14 at 16:29
  • 1
    @DrewNoakes: Indeed - shame BigDecimal remained cut though :( – Jon Skeet Aug 26 '14 at 17:07
  • 3
    @markshep: Agreed, although I'd argue that adding a copy/paste comment to almost all answers isn't actually a good idea. But for someone wanting to work with large integers, `BigInteger` is likely to be the best solution. Extra work would be required to make it overflow in the same way as an Int128, of course. – Jon Skeet Aug 15 '16 at 10:53
6

BigInteger is now a standard part of C# and friends in .NET 4.0. See: Gunnar Peipman's ASP.NET blog.

Note that the CPU can generally work with ordinary integers much more quickly and in constant time, especially when using the usual math operators (+, -, /, ...) because these operators typically map directly to single CPU instructions.

With BigInteger, even the most basic math operations are much slower function calls to methods whose runtime varies with the size of the number. This is because BigInteger implements arbitrary precision arithmetic, which adds considerable but necessary overhead. The benefit is that BigIntegers are not limited to 64 or even 128 bits, but by available system memory (or about 264 bits of precision, whichever comes first).
Read here.

phuclv
  • 37,963
  • 15
  • 156
  • 475
Charles Burns
  • 10,310
  • 7
  • 64
  • 81
  • 2
    @markshep: I realize that, but BigInteger fulfills the requirement, `I need to do some large integer math.` I think my mistake was in not mentioning that it fulfill the requirement, `implement[s] all of the usual operators"`. I have edited the answer to reflect this, and added some notes on arbitrary precision arithmetic. – Charles Burns Aug 15 '16 at 15:22
  • What do you mean by "Note that BigInteger does not support the usual operators"? – Aluan Haddad Feb 25 '18 at 14:03
  • 1
    @AluanHaddad: I had meant that BigInteger operators were overloaded, not just simple 1:1 mappings with a CPU instruction, but that was clear as mud so I rewrote that part of the post. – Charles Burns Feb 26 '18 at 18:25
4

GUID is backed by a 128 bit integer in .NET framework; though it doesn't come with any of the typical integer type methods.

I've written a handler for GUID before to treat it as a 128 bit integer, but this was for a company I worked for ~8 years ago. I no longer have access to the source code.

So if you need native support for a 128 bit integer, and don't want to rely on BigInteger for whatever reason, you could probably hack GUID to server your purposes.

Brett Allen
  • 5,297
  • 5
  • 32
  • 62
  • 2
    That would be okay for storage, but if I wanted to add, subtract, multiply, etc, I'd probably be better using something else – Adam Tegen Feb 26 '18 at 19:43
  • Correct. We were using it as a bit mask (updated column in database from 64bit to guid), so storage was all we needed it for. Time constraints of feature improvement lead to the hacky solution. – Brett Allen Feb 26 '18 at 20:05
3

C# PCL library for computations with big numbers such as Int128 and Int256. https://github.com/lessneek/BigMath

some_engineer
  • 1,844
  • 1
  • 19
  • 26
3

If you don't mind making reference to the J# library (vjslib.dll included with VS by default) there is already and implementation of BigInteger in .NET

using java.math;

public static void Main(){
    BigInteger biggy = new BigInteger(....)

}
sbeskur
  • 2,260
  • 23
  • 23
-3

I believe Mono has a BigInteger implementation that you should be able to track down the source for.

Craig
  • 4,323
  • 2
  • 29
  • 32