Storing very large numbers in Java - java

I'd like to store a long integer in Java, specifically the 6144-bit MODP Group (Group 17) from RFC 3526. However this number does not seem to fit to a BigInteger. Is there a way to use this prime number in Java?
EDIT: I tried
BigInteger p = new BigInteger(Integer.toString(pValue));
p = 33751521821438561184518523159967412330064897805741846548173890474429429901326672445203235101919165483964194359460994881062089387893762814044257438204432573941083014827006090258925875161018096327732335800595831915976014208822304007327848132734933297885803213675261564962603340457220776826322500058091310967253976619973988033663666385188155212656268079501726223369693427999804134467810120772356498596945532366527400517575471969335854905274504119509592366013711954148258884879224599915203456315881034776553083676995718335598586395591169999570824515035017543533352697525287753332500527176569576894926734950469293596134095086603716860086302051544539652689091299099784588919052383463057789440565460681441902442399956419060521629604697347879024654313800186078316526964529288062740879011035175920059192178561473199006205896719435014765345518490882366607110905303449152556221163232127426440691921134648766635695850239231304591744215610985029636895406718880766308249227315984267542266259489684372223916445411015900506239419267909716320331208988978180868987431623710347617992356201449023892203230133009421463914291201346063125219636964261683591541014344239275340735690997732222069758773963390876360546515755280517042160525487302898122311669799679447530453600399342697032714458549591285939453949034981248114322322367238645042515984447890788917823576330019151696568654314153058547592091366014550143819685170068343700104677609041166369760080933413605498962382077778845599834907475953430787446201384567328530675275792962354883770806900827183685718353469574731680520621944540947734619035177180057973022652571032196598229259194875709994709721793154158686515748507274224181316948797104601068212015232921691482496346854413698719750190601102705274481050543239815130686073601076304512284549218459846046082253596762433827419060089029417044871218316020923109988915707117567;

Use the BigInteger(String val) constructor to create the number, that is: pass the number as a String. The BigInteger class implements an arbitrary-precision integer data type, any integer can fit - as long as there's enough physical memory to represent it:
BigInteger p = new BigInteger("33751521821438561184518523159967412330064897805741846548173890474429429901326672445203235101919165483964194359460994881062089387893762814044257438204432573941083014827006090258925875161018096327732335800595831915976014208822304007327848132734933297885803213675261564962603340457220776826322500058091310967253976619973988033663666385188155212656268079501726223369693427999804134467810120772356498596945532366527400517575471969335854905274504119509592366013711954148258884879224599915203456315881034776553083676995718335598586395591169999570824515035017543533352697525287753332500527176569576894926734950469293596134095086603716860086302051544539652689091299099784588919052383463057789440565460681441902442399956419060521629604697347879024654313800186078316526964529288062740879011035175920059192178561473199006205896719435014765345518490882366607110905303449152556221163232127426440691921134648766635695850239231304591744215610985029636895406718880766308249227315984267542266259489684372223916445411015900506239419267909716320331208988978180868987431623710347617992356201449023892203230133009421463914291201346063125219636964261683591541014344239275340735690997732222069758773963390876360546515755280517042160525487302898122311669799679447530453600399342697032714458549591285939453949034981248114322322367238645042515984447890788917823576330019151696568654314153058547592091366014550143819685170068343700104677609041166369760080933413605498962382077778845599834907475953430787446201384567328530675275792962354883770806900827183685718353469574731680520621944540947734619035177180057973022652571032196598229259194875709994709721793154158686515748507274224181316948797104601068212015232921691482496346854413698719750190601102705274481050543239815130686073601076304512284549218459846046082253596762433827419060089029417044871218316020923109988915707117567");

That number will easily fit into a Java BigInteger, but both methods you're using to get it are using an intermediate form into which it cannot fit:
BigInteger p = new BigInteger(Integer.toString(pValue));
p = 337515218214385611845185231599674123300648978057418465481...7117567;
The former won't work because the Integer class cannot hold a number that big. The latter won't work because a "naked" number in your source code is treated as an int.
With the actual hex value taken from RFC3526, the following program shows how to do it:
import java.math.BigInteger;
public class Test
{
public static void main(String[] args) {
BigInteger num = new BigInteger(
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" +
"8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B" +
"302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9" +
"A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6" +
"49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8" +
"FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D" +
"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C" +
"180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718" +
"3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D" +
"04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D" +
"B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226" +
"1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C" +
"BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC" +
"E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26" +
"99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB" +
"04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2" +
"233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127" +
"D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" +
"36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406" +
"AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918" +
"DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B33205151" +
"2BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03" +
"F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97F" +
"BEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" +
"CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58B" +
"B7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632" +
"387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E" +
"6DCC4024FFFFFFFFFFFFFFFF", 16);
System.out.println(num);
}
}
The output of that program is:
33751521821438561184518523159...8915707117567

Related

I tried to calculate the hashCode for some String but failed, what am I doing wrong?

I know that algorithm for a String hashCode is
s[0]*31^(n - 1) + s[1]*31^(n - 2) + ... + s[n - 1]
I tried to calculate on calculator what hashCode would If I have a String like this
String s = new String("blue");
Using the algorithm (for conversion from char to int I used ASCII converter) I have:
98*31^(3) + 108*31^2 + 117*31 + 101 + 98 + 108 + 117 +101 = 3027458
But when I type:
public static void main(String[] args) {
String s = new String("blue");
System.out.println(s.hashCode());
}
I get output: 3027034
What am I doing wrong? Why the hashCode is not like it's supposed to be according to the algorithm?
I think you are misreading the formula. Try doing this:
98*(31^3) + 108*(31^2) + 117*(31^1) + 101*(31^0)
This will output:
3027034
The extra additions at the end that you have are not part of the formula.
s[n-1] is used to show that the pattern of the formula continues for the entire String.
I added the 31^1 and 31^0 back into the complete formula to show clearly how it exactly is being calculated. Note that 101*(31^0) is just 101*1 which can be written s[n-1] for the final value.

How to write a maths expression in terms of x in Java

I am trying to write a function that parses in 2 numbers e.g. coefficient 5 and power 3. I want the output response to be 5x^3.
public void Variable(double c, double p)
{
coefficient = c;
power = p;
}
public Expression derive()
{
System.out.print("Youre term is " + coefficient + "" + Math.pow("x",power));
}
What have I done wrong here? It's not accepting my "x" in the pow function. But I'm not sure how to have a simple letter in there?
Cheers
Math.pow(double a, double b) doesn't accept a string as its first argument. It expects a double for both the base and the exponent. That method is for calculating values based on the base and the exponent supplied.
-> Returns the value of the first argument raised to the power of the second argument.
Instead, what you want to achieve can easily be done without using pow() method.
Just display coefficient + "x ^ " + power to the console.
System.out.print("Your term is " + coefficient + "x^" + power);

Converting a double to a string fraction(shoe sizes)

So for my project I have to write a method to convert double values to a string. I understand how to do this multiple ways multiple options of formatting. What I'm confused about is how would I turn half sizes(shoes) into a fraction version while still converting it to a string. So
10.5
returns
10 - 1/2
Any tips or helpful pointers are appreciated. Sorry if this is a dumb question I am still learning. :)
What you want can be done with the modulus operator (%) which in Java can be used with floating point values. If you do shoeSize % 1 you will get 0.5 with half sizes and 0.0 with others, so you only have to check that value to add the "1/2" to the string representation or not. Here is a simple example
public class ShoeSize {
double size;
public ShoeSize(double size) { this.size = size; }
public String toString() {
return "" + (int)size + (size % 1 == 0.5? " 1/2" : "");
}
public static void main(String args[]) {
ShoeSize ss1 = new ShoeSize(10.5);
ShoeSize ss2 = new ShoeSize(11);
ShoeSize ss3 = new ShoeSize(11.5);
System.out.println(ss1);
System.out.println(ss2);
System.out.println(ss3);
}
}
The result of the previous code is:
10 1/2
11
11 1/2
However, you really shouldn't go with that approach. That is because depending on the way you manage the shoe size values it can lead to unpredictable results, just because arithmetic in floating point values is not precise as it is with integer values. Some simple operations like the following can introduce enough error so the result is not what you expect:
...
public static void main(String args[]) {
ShoeSize ss = new ShoeSize(10.0);
ss.size += 0.1 + 0.2 + 0.3; // Sum it half
System.out.println(ss);
}
This code now prints 10 instead of 10 1/2.
What should you do instead? Well, there are several ways. You could for example store the shoe size inside ints representing, with each unit representing a half. This internal representation will be much error-prone if you have operations like addSize or subtracts. The only problem will be reading the size of the user; the best way is probably having a list of predefined sizes for the user to choose. Here is an example:
public class ShoeSize {
int halves;
public ShoeSize(double size) { this.halves = (int)(size * 2); }
public String toString() {
return "" + (halves / 2) + (halves % 2 == 1? " 1/2": "");
}
public static void main(String args[]) {
ShoeSize ss = new ShoeSize(10.5);
System.out.println(ss);
}
}
Still better, since the shoe sizes use to be very restricted between certain values, you could represent their values in a single enum. Every enum can be constructed from the human-readable string of the size (ex. "10 1/2") and there would never be problems with invalid shoe sizes. The only problem with this approach is the need to define a custom method to obtain the next and previous shoe sizes, but here is a question that can help you with that:
[What's the best way to implement `next` and `previous` on an enum type?
Try this
public String getShoeSize(double size) {
int s = (int)size;
String shoeSize = Integer.toString(s);
//check if it is a half value
if(size > s) {
shoeSize += " - 1/2";
}
return shoeSize;
}
At first convert value of double to string and split it:
double d=10.5;
String s = String.valueOf(d);
String[] newstr =s.split(".");
then if fraction is limited use switch case for .5 , .25 , .75
but it is not limited ,simplifying fractions is easy if you can folow the steps:
pay attention to this point that maybe your number is not point sign for example 10 that in switch case must be considered
1.find gcd of both num and den, so you have gcd=GCDFind(gcd, num);
2.now, if gcd==1, then the fraction cannot be simplified (it is already in simplified form).
3.if gcd > 1, then newNum = num/gcd; and newDen = den/gcd;
example for limited :
double s = 10.25;
String aString = Double.toString(s);
String[] fraction = aString.split("\\.");
int denominator = (int)Math.pow(10, fraction[1].length());
int numerator = Integer.parseInt(fraction[0] + "" + fraction[1]);
int t=numerator%denominator;
switch(t){
case 0: System.out.println(numerator/denominator);break; //example : 10
case 5: System.out.println(numerator/denominator + " - " +"1/2");break; //example : 10.5
case 25: System.out.println(numerator/denominator + " - " +"1/4");break; //example : 10.25
case 75: System.out.println(numerator/denominator + " - " +"3/4");break; //example : 10.75
default:System.out.println("Not in 1/2, 1/4 or 3/4");
}

How do I use "BigDecimal" in Java for my specific code?

I'm very new to programming in Java. I have been given an assignment in my school to solve the following exercise:
"Create two variables, each containing a number. Put out a message that shows how often the second number fits into the first one, and the rest (if there is one)" [I hope the wording is clear. I'm translating this from my native language german into english]
Now in general, I have solved the exercise like this (using Netbeans):
double numberOne = 10, numberTwo = 35.55;
double result, rest;
String conversion, numberOutput;
result = numberTwo / numberOne;
conversion = Double.toString(result);
int indexOfComma = conversion.indexOf(".");
numberOutput = conversion.substring(0, indexOfComma);
rest = numberTwo % numberOne;
System.out.println("The second number fits " + numberOutput +
" times into the first one. The rest is: " + rest);
With the numbers provided, the system pops out this message:
"The second number fits 3 times into the first one. The rest is: 5.549999999999997"
I don't like the rounding error for the rest. I expected it to give out "5.55" like a human would type or write it. After a bit of googling around it seems that something called "BigDecimal" is the solution to my problem, but the explanations I found of how to implement this in Java go wayyy over my head.
Would you be so kind as to show me exactly where and how I need to use BigDecimal in the above code to get the desired output? I would also be happy to see any alternative solutions you can think of.
BigDecimal version of your code:
BigDecimal numberOne = new BigDecimal("10");
BigDecimal numberTwo = new BigDecimal("35.55");
BigDecimal[] divRem = numberTwo.divideAndRemainder(numberOne);
System.out.println("The second number fits " + divRem[0].stripTrailingZeros().toPlainString() +
" times into the first one. The rest is: " + divRem[1].stripTrailingZeros().toPlainString());
Output
The second number fits 3 times into the first one. The rest is: 5.55
You can use BigDecimal like
BigDecimal a = BigDecimal.valueOf(10);
BigDecimal b = BigDecimal.valueOf(35.55);
BigDecimal c = b.divide(a, 3, BigDecimal.HALF_UP);
System.out.println(b + " / " + a + " = " + c);
Or you could use rounding like
System.out.printf("(int)(%.2f / %d) = %d%n", 35.55, 10, (int) (35.55 / 10));
System.out.printf("%.2f %% %d = %.2f%n", 35.55, 10, 35.55 % 10);
which prints
floor(35.55 / 10) = 3
35.55 % 10 = 5.55

Long datatype throwing numberformatexception

A datatype long in Java 7 is throwing numberformatexception when it is exceeding 20 digits. Is there any alternative here?
You can use BigIntegers to do mathematical operations with higher number of digits.
But in division, it is doing integer division.(As in integer data types). For large decimal number calculations, you can use BigDecimal
An Example using BigInteger is shown below..
BigInteger b1 = new BigInteger("100000000000000000000000000000000000000000");
BigInteger b2 = new BigInteger("100000");
System.out.println("Addition: " + b1.add(b2));
System.out.println("Subtraction: " + b1.subtract(b2));
System.out.println("Division: " + b1.divide(b2));
System.out.println("Multiplication: " + b1.multiply(b2));
System.out.println("Power: " + b1.pow(1000));
For more information you can just google how to use biginteger in java

Categories

Resources