Java multiplying two BigInt objects - java

Theres a BigInt class and two objects num1 and num2. I have a lab assignment and i have to multiply num1 and num2. they can be an integer up to 50 digits. the class has a size and a digit.size is the number of digits in the integer that is entered and digit is an array that holds the integer.
I have to write a method that multiplies these two objects and returns the product. Im a little confused on how to start this. Ive seen examples where there are two loops and a base. I have no idea what the base would be used for.
any pointers in the right direction would be appreciated.

I assume base is decimal / hexadecimal etc., for a more general implementation...
Generally, you need to use normal long multiplication, like learned in school.
Also note that the result could be up to 100 digits in length - if you just need the 50 least significant, you could optimize the long multiplication a bit (pretty much cut it in half).

Related

Java (suggestion) - implement double as two integers?

In java, double takes 64 bits, but stores (or computes with) numbers unprecisely.
E.g. the following code:
double a = 10.125d;
double b = 7.065d;
System.out.println(a-b);
prints out 3.0599999999999996 rather than 3.06.
So, the question - what about utilizing those 64 bits to store two 32-bit integers (first to represent the whole part, second the decimal part)?
Then calculations would be precise, right?
The naive pseudo-code implementation with unhandled decimal transfer:
primitive double {
int wholePart;
int decimalPart;
public double + (double other) {
return double (this.wholePart + other.wholePart, this.decimalPart + other.decimalPart);
}
//other methods in the same fashion
public String toString() {
return wholePart + "." + decimalPart;
}
}
Is there a reason for Java to store double unprecisely and not to use the implementation mentioned above?
There is one big problem with your solution. int are signed, therefore it would be able to have negative decimal parts which don't make sense. Other than that you could not store the same range of values with your solution and you would be missing the values Double.NEGATIVE_INFINITY, Double.NaN and Double.POSITIVE_INFINITY. See how floating point are stored in binary e.g. in this SO question to understand why that is or read IEEE 754, which is the standard which defines how floating point numbers are stored in binary.
But yes, generally speaking if you need the precision it's a good idea to work with integer arithmetic instead of floating point arithmetic (again, for the reasons why see above linked question). The easiest way is to just pick another unit/ the smallest unit you'll need.
Assume for example you want to calculate prices in euros €. If you store them as floats you'll risk being inaccurate which you really don't want when working with prices. Therefore instead of storing € amounts, store how many cents (smallest possible unit here) something costs and you'll have eliminated the problem.
For large integer there also is BigInteger so that approach can also work for large or respectively very small float values.

How to calculate any power of a base 2 number in Java by not using BigInteger?

How can I calculate in Java any power of a number in a base 2 (2^n, where n can be any number), without using the BigInteger class?
Let's say I got the binary number 100000000000000000000100000000001 stored in a given array, and I want to print its value in a decimal number (just to print it, let's say we store it in a String type).
I'm not sure I understand your problem completely, but if n is the binary number converted to a decimal number, then you are playing with way too large numbers.
Consider the binary number as decimal. Your example would be the decimal number 4294969345. Just try to consider what 2^4294969345 would be. As an example 2^429 would be 1.38633485×10^129. There's no way you can execute this.
I agree with the others, please share your code, and maybe you can get a better answer.
EDIT: If it's just a conversion from the big binary number to a decimalnumber, you can use Long.parseLong(binaryNumber, 2), where binaryNumber is your binary number as a String.
The values needs to be saved somewhere to be "just printed", whether a data structure or a primitive, in your case it's way too large for an integer ( > 2^31), you can use long instead (Long.parseLong(binary, 2)) but eventually if it keeps getting bigger, you will need another way, either using BigInteger or your own brains.

Java BigInteger pow with BigInteger exponent

Hi i want to calculate
2^(256bit number)
in java, but biginteger's pow function just can handle ints.
How can i calculate with larger numbers?
Is there any library?
i want to calculate all numbers from
2^0
2^1
2^2
...
2^(10^77)
I suspect the reason they didn't bother including anything like this is that in most cases, the number would be too big to represent.
Consider 2^(256 bit number). The result has (256bit number) bits, meaning that it takes more memory then there are particles in the universe.
So you'll have to find a different way to represent your logic. Perhaps you could do it symbolically.
It would be possible to do 2^(2^32) and exponents close to that, but this was probably seen as a niche case that they just didn't bother adding a function for.

How does BigInteger store its data?

I've been searching around for quite a while, and I've found almost nothing on how BigInteger actually holds its numbers. Are they an array of chars? Something else? And how is data converted to/from BigInteger?
From what I've found, I am assuming that all of arbitrary precision classes, like BigInteger and BigDecimal, hold data as a character array. Is this how it actually works? Or is it just people's guess?
I'm asking because I have been working on my own implementation of something like BigInteger, but I can't figure out how to hold numbers larger than Long.MAX_VALUE (I don't remember the actual number).
Thanks in advance.
With an int[]
From the source:
/**
* The magnitude of this BigInteger, in <i>big-endian</i> order: the
* zeroth element of this array is the most-significant int of the
* magnitude. The magnitude must be "minimal" in that the most-significant
* int ({#code mag[0]}) must be non-zero. This is necessary to
* ensure that there is exactly one representation for each BigInteger
* value. Note that this implies that the BigInteger zero has a
* zero-length mag array.
*/
final int[] mag;
The most common way of representing numbers is by using the positional notation system. Numbers are written using digits to represent multiples of powers of the specified base. The base that we are most familiar with and use everyday, is base 10. When we write the number 12345 in base 10, it actually means: 12345 = 1*10^4 + 2*10^3 + 3*10^2 + 4*10^1 + 5*10^0
Continued here...
There are many ways to represent big integers. Strings of characters is simple,
and anyone who has ever done long division with pencil and paper can write the
arithmetic routines.

Using logarithm instead of division for large numbers?

I couldn't really come up with a proper title for my question but allow me to present my case; I want to calculate a significance ratio in the form: p = 1 - X / Y
Here X comes from an iterative process; the process takes a large number of steps and counts how many different ways the process can end up in different states (stored in a HashMap). Once the iteration is over, I select a number of states and sum their values. It's hard to tell how large these numbers are so I am intending to implement the sum as BigInteger.
Y, on the other hand comes from a binomial coefficient with numbers in thousands-scale. I am inclined to use logGamma to calculate these coefficients, which as a result give me the natural logarithm of the value.
What I am interested in is to do division X / Y in the best/most effective way. If I can get X in the natural logarithm then I could subtract the powers and have my result as 1 - e ^ (lnX - lnY).
I see that BigInteger can't be logarithmized by Math.log, what can I do in this case?
You may be able to use doubles. A double can be extremely large, about 1.7e308. What it lacks is precision: it only supports about 15 digits. But if you can live with 15 digits of precision (in other words, if you don't care about the difference between 1,000,000,000,000,000 and 1,000,000,000,000,001) then doubles might get you close enough.
If you are calculating binomial coefficients on numbers in the thousands, then Doubles will not be good enough.
Instead I would be inclined to call the toString method on the number, and compute the log as log(10) * number.toString().length() + log(asFloat("0." + number.toString()) where asFloat takes a string representation of a number and converts it to a float.
If you need maximum precision, how about converting the BigIntegers into BigDecimals and doing algebra on them. If precision isn't paramount, then perhaps you can convert your BigIntegers into doubles and do simple algebra with them. Perhaps you can tell us more about your problem domain and why you feel logarithms are the best way to go.

Categories