Math with very large numbers using strings - c#

I'm trying to use strings to do math with very large numbers using strings, and without external libraries.
I have tried looking online with no success, and I need functions for addition, subtraction, multiplication, and division (if possible, and limited to a specified number of decimal places.)
example: add 9,900,000,000
and 100,000,020
should be 10,000,000,020.
EDIT: Im sorry I diddn't be specific enough, but I can only use Strings. no Long, bigInt, anything.
just the basic string and if nessecary, int32.
This is NOT a homework question!

Have you looked at BigInteger ?

If you're using .NET Framework 4, you can make use of the new System.Numerics.BigInteger class, which is an integer that can hold any whole number at all, until you run out of memory.
(The examples you provide, by the way, can be computed using long or System.UInt64.)

You have to convert the value in bits first & then apply the operation which you wish. After operation, you should convert back the bits to the number.

Related

C# Scientific calculation - big number with many decimals

I have a problem that I need advice: I have to make calculations with big numbers, in the range of (plus/minus, signed); integer part: 70*(10^27) and accuracy, decimal part: 9*(10^-31). Most of the times I only simple simple operations (add/subtr/mult/div) where I could ignore most digits (use only 8 decimals) of the decimal part - however, in many cases, I would have to take the 'whole' decimal and do calculations with that precision (and store the result which is used in subsequent calculations).
An example of a number:
66898832014839425790021345548 . 8499970865478385639546957014538
I saw the articles on decimal vs long etc. Should I use a decimal or should a custom type be made? If yes on the later, how may I do simple arithmetic operations? (Roundation of the last decimal only is acceptable)
My projects are all in C# and SQL Server; thank you very much in advance.
There is no standard implementation in C#, but you can create your own library based on BigInteger like
public BigDecimal(BigInteger integer, BigInteger scale)
You can also reference some 3rd-party libraries like GMP with its .Net forks/ports like Math.Gmp.Native.NET, libgmp, etc.
There are some custom libs, as Franz Gleichmann already mentioned in his comment: BigDecimal, AngouriMath
For SQL Server most of the libraries use strings to store such kind of data. For instance, in Java there is BigDecimal and it is mapped to string via JDBC.

C# math expression parser to work with big numbers

I work on a .net project and need a math expression parser to calculate simple formulas.
I used mXparser but it seemed unable to work with big decimal numbers(more than 16 digits) .
For example, the result of formula has to be 2469123211254289589
but it returns 2.46912321125428E+17 and when I use decimal.parse to convert it to decimal it gives me 2469123211254280000.
Is there another parser to solve this problem?
or
Is there another way to deal with this problem?
If you're happy dealing with integers then you should be able to use BigInteger to carry out these sorts of operations.
It has no theoretical upper or lower bounds so you shouldn't have a problem (unless you run out of memory to store that number that is).

Why is the division result between two integers truncated?

All experienced programmers in C# (I think this comes from C) are used to cast on of the integers in a division to get the decimal / double / float result instead of the int (the real result truncated).
I'd like to know why is this implemented like this? Is there ANY good reason to truncate the result if both numbers are integer?
C# traces its heritage to C, so the answer to "why is it like this in C#?" is a combination of "why is it like this in C?" and "was there no good reason to change?"
The approach of C is to have a fairly close correspondence between the high-level language and low-level operations. Processors generally implement integer division as returning a quotient and a remainder, both of which are of the same type as the operands.
(So my question would be, "why doesn't integer division in C-like languages return two integers", not "why doesn't it return a floating point value?")
The solution was to provide separate operations for division and remainder, each of which returns an integer. In the context of C, it's not surprising that the result of each of these operations is an integer. This is frequently more accurate than floating-point arithmetic. Consider the example from your comment of 7 / 3. This value cannot be represented by a finite binary number nor by a finite decimal number. In other words, on today's computers, we cannot accurately represent 7 / 3 unless we use integers! The most accurate representation of this fraction is "quotient 2, remainder 1".
So, was there no good reason to change? I can't think of any, and I can think of a few good reasons not to change. None of the other answers has mentioned Visual Basic which (at least through version 6) has two operators for dividing integers: / converts the integers to double, and returns a double, while \ performs normal integer arithmetic.
I learned about the \ operator after struggling to implement a binary search algorithm using floating-point division. It was really painful, and integer division came in like a breath of fresh air. Without it, there was lots of special handling to cover edge cases and off-by-one errors in the first draft of the procedure.
From that experience, I draw the conclusion that having different operators for dividing integers is confusing.
Another alternative would be to have only one integer operation, which always returns a double, and require programmers to truncate it. This means you have to perform two int->double conversions, a truncation and a double->int conversion every time you want integer division. And how many programmers would mistakenly round or floor the result instead of truncating it? It's a more complicated system, and at least as prone to programmer error, and slower.
Finally, in addition to binary search, there are many standard algorithms that employ integer arithmetic. One example is dividing collections of objects into sub-collections of similar size. Another is converting between indices in a 1-d array and coordinates in a 2-d matrix.
As far as I can see, no alternative to "int / int yields int" survives a cost-benefit analysis in terms of language usability, so there's no reason to change the behavior inherited from C.
In conclusion:
Integer division is frequently useful in many standard algorithms.
When the floating-point division of integers is needed, it may be invoked explicitly with a simple, short, and clear cast: (double)a / b rather than a / b
Other alternatives introduce more complication both the programmer and more clock cycles for the processor.
Is there ANY good reason to truncate the result if both numbers are integer?
Of course; I can think of a dozen such scenarios easily. For example: you have a large image, and a thumbnail version of the image which is 10 times smaller in both dimensions. When the user clicks on a point in the large image, you wish to identify the corresponding pixel in the scaled-down image. Clearly to do so, you divide both the x and y coordinates by 10. Why would you want to get a result in decimal? The corresponding coordinates are going to be integer coordinates in the thumbnail bitmap.
Doubles are great for physics calculations and decimals are great for financial calculations, but almost all the work I do with computers that does any math at all does it entirely in integers. I don't want to be constantly having to convert doubles or decimals back to integers just because I did some division. If you are solving physics or financial problems then why are you using integers in the first place? Use nothing but doubles or decimals. Use integers to solve finite mathematics problems.
Calculating on integers is faster (usually) than on floating point values. Besides, all other integer/integer operations (+, -, *) return an integer.
EDIT:
As per the request of the OP, here's some addition:
The OP's problem is that they think of / as division in the mathematical sense, and the / operator in the language performs some other operation (which is not the math. division). By this logic they should question the validity of all other operations (+, -, *) as well, since those have special overflow rules, which is not the same as would be expected from their math counterparts. If this is bothersome for someone, they should find another language where the operations perform as expected by the person.
As for the claim on perfomance difference in favor of integer values: When I wrote the answer I only had "folk" knowledge and "intuition" to back up the claim (hece my "usually" disclaimer). Indeed as Gabe pointed out, there are platforms where this does not hold. On the other hand I found this link (point 12) that shows mixed performances on an Intel platform (the language used is Java, though).
The takeaway should be that with performance many claims and intuition are unsubstantiated until measured and found true.
Yes, if the end result needs to be a whole number. It would depend on the requirements.
If these are indeed your requirements, then you would not want to store a decimal and then truncate it. You would be wasting memory and processing time to accomplish something that is already built-in functionality.
The operator is designed to return the same type as it's input.
Edit (comment response):
Why? I don't design languages, but I would assume most of the time you will be sticking with the data types you started with and in the remaining instance, what criteria would you use to automatically assume which type the user wants? Would you automatically expect a string when you need it? (sincerity intended)
If you add an int to an int, you expect to get an int. If you subtract an int from an int, you expect to get an int. If you multiple an int by an int, you expect to get an int. So why would you not expect an int result if you divide an int by an int? And if you expect an int, then you will have to truncate.
If you don't want that, then you need to cast your ints to something else first.
Edit: I'd also note that if you really want to understand why this is, then you should start looking into how binary math works and how it is implemented in an electronic circuit. It's certainly not necessary to understand it in detail, but having a quick overview of it would really help you understand how the low-level details of the hardware filter through to the details of high-level languages.

A value larger than ULong? Computing 100!

I'm trying to compute 100! and there doesn't seem to be a built-in factorial function. So, I've written:
Protected Sub ComputeFactorial(ByVal n As ULong)
Dim factorial As ULong = 1
Dim i As Integer
For i = 1 To n
factorial = factorial * i
Next
lblAnswer.Text = factorial
End Sub
Unfortunately, running this with the value of 100 for n rseults in
Value was either too large or too
small for a UInt64.
So, is there a larger data type for holding numbers? Am i mistaken in my methods? Am I helpless?
Sounds like Project Euler.
.NET 4.0 has System.Numerics.BigInteger, or you can pick up a pretty sweet implementation here:
C# BigInteger Class
Edit: treed :(
I'll add - the version at CodeProject has additional features like integer square root, a primality test, Lucas sequence generation. Also, you don't have direct access to the buffer in the .NET implementation which was annoying for a couple things I was trying.
Until you can use System.Numerics.BigInteger you are going to be stuck using a non-Microsoft implementation like BigInteger on Code Project.
Hint: use an array to store the digits of the number. You can tell by inspection that the result will not have more than 200 digits.
You need an implementation of "BigNums". These are integers that dynamically allocate memory so that they can hold their value.
A version was actually cut from the BCL.
The J# library has an implementation of java.math.BigInteger that you can use from any language.
Alternatively, if precision/accuracy are not a concern (you only care about order of magnitude), you can just use 64-bit floats.
decimal will handle 0 through +/-79,228,162,514,264,337,593,543,950,335 with no decimal point(scale of zero)

Converting to int16, int32, int64 - how do you know which one to choose?

I often have to convert a retreived value (usually as a string) - and then convert it to an int. But in C# (.Net) you have to choose either int16, int32 or int64 - how do you know which one to choose when you don't know how big your retrieved number will be?
Everyone here who has mentioned that declaring an Int16 saves ram should get a downvote.
The answer to your question is to use the keyword "int" (or if you feel like it, use "Int32").
That gives you a range of up to 2.4 billion numbers... Also, 32bit processors will handle those ints better... also (and THE MOST IMPORTANT REASON) is that if you plan on using that int for almost any reason... it will likely need to be an "int" (Int32).
In the .Net framework, 99.999% of numeric fields (that are whole numbers) are "ints" (Int32).
Example: Array.Length, Process.ID, Windows.Width, Button.Height, etc, etc, etc 1 million times.
EDIT: I realize that my grumpiness is going to get me down-voted... but this is the right answer.
Just wanted to add that... I remembered that in the days of .NET 1.1 the compiler was optimized so that 'int' operations are actually faster than byte or short operations.
I believe it still holds today, but I'm running some tests now.
EDIT: I have got a surprise discovery: the add, subtract and multiply operations for short(s) actually return int!
Repeatedly trying TryParse() doesn't make sense, you have a field already declared. You can't change your mind unless you make that field of type Object. Not a good idea.
Whatever data the field represents has a physical meaning. It's an age, a size, a count, etc. Physical quantities have realistic restraints on their range. Pick the int type that can store that range. Don't try to fix an overflow, it would be a bug.
Contrary to the current most popular answer, shorter integers (like Int16 and SByte) do often times take up less space in memory than larger integers (like Int32 and Int64). You can easily verify this by instantiating large arrays of sbyte/short/int/long and using perfmon to measure managed heap sizes. It is true that many CLR flavors will widen these integers for CPU-specific optimizations when doing arithmetic on them and such, but when stored as part of an object, they take up only as much memory as is necessary.
So, you definitely should take size into consideration especially if you'll be working with large list of integers (or with large list of objects containing integer fields). You should also consider things like CLS-compliance (which disallows any unsigned integers in public members).
For simple cases like converting a string to an integer, I agree an Int32 (C# int) usually makes the most sense and is likely what other programmers will expect.
If we're just talking about a couple numbers, choosing the largest won't make a noticeable difference in your overall ram usage and will just work. If you are talking about lots of numbers, you'll need to use TryParse() on them and figure out the smallest int type, to save ram.
All computers are finite. You need to define an upper limit based on what you think your users requirements will be.
If you really have no upper limit and want to allow 'unlimited' values, try adding the .Net Java runtime libraries to your project, which will allow you to use the java.math.BigInteger class - which does math on nearly-unlimited size integer.
Note: The .Net Java libraries come with full DevStudio, but I don't think they come with Express.

Categories

Resources