How do i concatenate two BigInteger variables together? - java

I have two BigInteger variables "e" and "n" and i want to concatenate them together as "en".. how do i do this?
Do i need to convert to a string first then back to BigInteger?
My code sets the variables from another class.
public class Key {
public BigInteger getN() {
return n;
}
public void setN(BigInteger n) {
this.n = n;
}
public BigInteger getE() {
return e;
}
public void setE(BigInteger e) {
this.e = e;
}
public BigInteger getD() {
return d;
}
public void setD(BigInteger d) {
this.d = d;
}
public BigInteger e;
public BigInteger n;
public BigInteger d;
public BigInteger publickeyconcat() {
BigInteger myval = (e + n);
return myval;
}
public BigInteger privatekeyconcat(){
BigInteger myval2 = e;
return myval2;
}
}
UPDATE
Have tried the method given in the comments but when converting to use e and n rather than number1 and number2 it doesn't concat them together.
public BigInteger publickeyconcat() {
BigInteger ten=new BigInteger("10");
BigInteger myval=(e.multiply(ten.pow((int)(Math.floor(Math.log10(e.doubleValue()) + 1)))).add(n));
return myval;
}

Because of the effort shown, the power of 10 for multiplying the first number can be gotten as follows:
public static BigInteger concat(BigInteger x, BigInteger y)
{
int ndigits = y.bitLength() * 3 / 10; // Guessed number of digits using 2^10 ≈ 10^3.
BigInteger pow10 = BigInteger.TEN.pow(ndigits);
while (pow10.compareTo(y) > 0) {
pow10 = pow10.divide(BigInteger.TEN);
}
while (pow10.compareTo(y) <= 0) {
pow10 = pow10.multiply(BigInteger.TEN);
}
// Cheating: int ndigits = y.toString().length();
return x.multiply(pow10).add(y);
}

Since other answers have already focused on String Concatenation, let me give you another answer not involving String Concatenation. You can take the number of digits of first number, multiply first number with 10^(no of digits) and add the second number. A crude example would be as follows,
BigInteger ten=new BigInteger("10");
BigInteger number=new BigInteger("1234");
BigInteger number2=new BigInteger("5678");
BigInteger newBigInt=(number.multiply(ten.pow((int)(Math.floor(Math.log10(number.doubleValue()) + 1)))).add(number2));
System.out.println(newBigInt); //would print 12345678

If you just want to concatenate two BigInteger variables, you can do it this way:
public BigInteger publickeyconcat(BigInteger e, BigInteger n) {
String a = String.valueOf(e);
String b = String.valueOf(n);
String val = a + b;
BigInteger myval = new BigInteger(val);
return myval;
}
But if you want to do operations with the numbers, you can do that directly. There is no need for a conversion.

i did this in the end by converting to a string and using string buffer due to the size of BigInteger. I then left as String as i wanted to write it to a file but i could have reverted to BigInteger using the content variable.
public String publickeyconcat() {
String str = String.valueOf(e);
StringBuffer tmp = new StringBuffer(str);
tmp.append(n);
str = tmp.toString();
BigInteger content = new BigInteger(str);
return str;
}

Related

Conversion of decimal into binary using recursion

I want to convert the decimal number into a binary number using recursion in java. I tried a lot but unable to do it. Here is my code:
public class DecimalToBinary {
public static void main(String[] args) {
System.out.println(conversion(2));
}
public static int conversion(int n) {
return reconversion(n);
}
public static int reconversion(int n) {
if(n <= 0)
return 0;
else {
return (int) (n/2 + conversion(n/2));
}
}
}
Integer values are already in binary. The fact that they appear as digits 0 thru 9 when you print them is because they are converted to a string of decimal digits. So you need to return a String of binary digits like so.
public static String conversion(int n) {
String b = "";
if (n > 1) {
// continue shifting until n == 1
b = conversion(n >> 1);
}
// now concatenate the return values based on the logical AND
b += (n & 1);
return b;
}

Reverse a number using String builder in java

Problem Statement: Given a 32-bit signed integer, reverse digits of an integer.
Example 1:
Input: 123
Output: 321
Example 2:
Input: -123
Output: -321
My Solution:
class Solution7{
public int reverse(int x) {
if(x>Integer.MAX_VALUE || x<Integer.MIN_VALUE) {
return 0;
}
StringBuilder S_rev = new StringBuilder();
String S_r_v=S_rev.append(Math.abs(x)).reverse().toString();//.toString() String builder to String
double reverse_no=Double.parseDouble(S_r_v);
if (x < 0) {
return -(int)reverse_no;
}
return (int)reverse_no;
}
}
My Solution is ok for most of the test case. But it cannot pass one test case and I got a error
Error: Line 10: java.lang.NumberFormatException: For input string: "8463847412-"
If someone know what type of error it is please discuss.
Thank you in advance.
It seems like you are trying to pass in Integer.MIN_VALUE
When you pass in the minimum integer value, Math.abs seems to return a negative number as stated here
https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#abs-int-
Note that if the argument is equal to the value of Integer.MIN_VALUE, the most negative representable int value, the result is that same value, which is negative.
You can either check for x<=Integer.MIN_VALUE and return 0 if x is Integer.MIN_VALUE or handle the special case for Integer.MIN_VALUE
if(x== Integer.MIN_VALUE)
return -8463847412;
By converting number to String and reversing the sign symbol ended up on the end of the value. This makes the number invalid.
You don't have to convert to String or double. You can use module operator % to extract digits:
public int reverse(int x) {
long result = 0;
while (x != 0) {
result *= 10;
result += x % 10;
x /= 10;
}
if (result > Integer.MAX_VALUE || result < Integer.MIN_VALUE) {
throw new IllegalArgumentException(); // overflow
}
return result;
}
If you necessarily want to implement it using StringBuilder, here it is:
public static void main(String[] args) {
ReverseNum reverseNum = new ReverseNum();
System.out.println(reverseNum.reverse(-123));
System.out.println(reverseNum.reverse(123));
System.out.println(reverseNum.reverse(0));
}
public int reverse(int x) {
int res = 1;
String xStr = String.valueOf(x);
StringBuilder builder = null;
if (xStr.startsWith("-")) {
builder = new StringBuilder(xStr.substring(1));
res = -1;
} else {
builder = new StringBuilder(xStr);
}
return res * Integer.valueOf(builder.reverse().toString());
}
Output:
-321
321
0
P.S. If you want to avoid integer overflow, then you can simply use long instead of int, like this:
public long reverse(int x) {
long res = 1;
String xStr = String.valueOf(x);
StringBuilder builder = null;
if (xStr.startsWith("-")) {
builder = new StringBuilder(xStr.substring(1));
res = -1;
} else {
builder = new StringBuilder(xStr);
}
return res * Long.valueOf(builder.reverse().toString());
}
public class ReverseString {
public static void main(String args[]) {
ReverseString rs = new ReverseString();
System.out.println(rs.reverse(-84638));
System.out.println(rs.reverse(5464867));
}
public long reverse(int number) {
boolean isNegative = number < 0;
StringBuilder reverseBuilder = new StringBuilder();
String reversedString = reverseBuilder.append(Math.abs(number)).reverse().toString();
long reversedStringValue = Long.parseLong(reversedString);
if(isNegative) {
return reversedStringValue * -1;
} else {
return reversedStringValue;
}
}
}
This code provides the output you have mentioned in the requirement. And It also supports for integer overflow. Your requirement is to convert int values. It is okay to get the converted value in the higher format since converted value may not be in the range of int. I have changed the reverse method return type to long.
I have identified a few issues in your code.
public int reverse(int x) {
if(x>Integer.MAX_VALUE || x<Integer.MIN_VALUE) {
return 0;
}
Above code segment, not point of checking whether the value is inside the int range because it is already received in the param as a string. It should throw an error before executing your code lines since it is not able to fit the larger value to int variable.
Finally, the int number you have used is not in the int range. (-8463847412)
What about this?
public class ReverseNumber {
public static void main(String[] args) {
System.out.println(reverse(123456));
System.out.println(reverse(0));
System.out.println(reverse(-987654));
}
private static int reverse(int i) {
final int signum;
if(i < 0) {
signum = -1;
} else {
signum = +1;
}
int reversedNumber = 0;
int current = Math.abs(i);
while(0 < current) {
final int cipher = current % 10;
reversedNumber = Math.addExact(Math.multiplyExact(reversedNumber, 10), cipher);
current = current / 10;
}
return signum * reversedNumber;
}
}
Output:
654321
0
-456789
This solution avoids strings and can handle negative numbers.
It throws an Arithmetic exception if an integer overflow happens.

Extended Euclidean algorithm JAVA RSA

I´m trying to implement the EEA. I found this pattern which I use also.
extended_euclid(a,b)
1 if b = 0
2 than return (a,1,0)
3 (d',s',t') <-- extended_euclid(b, a mod b)
4 (d,s,t) <--- (d',t',s' - (a div b)t')
5 return (d,s,t)
And my code looks like this:
public static Triple extendedEuclid(BigInteger a, BigInteger b) {
if (b.equals(new BigInteger("0"))) {
return new Triple(a, new BigInteger("1"), new BigInteger("0"));
} else {
Triple i = extendedEuclid(b, a.mod(b));
return new Triple(i.getA(), i.getB(), (i.getC().divide(i.getB()).multiply(i.getC())));
}
}
I´m not quite sure if my code is correct. I looked up many pages like twenty or so but I still don´t get it. I´m mentally stuck.
Thanks.
It looks like you got the operations in the final return out of order. You also implemented the third value of Triple incorrectly. Here is my implementation. (I also used BigInteger's helper constants/methods + renamed variables for clarity.)
public class ExtendedEuclidAlgorithm {
public static void main(final String[] args) {
System.out.println("eea(240, 46) = " + apply(BigInteger.valueOf(240), BigInteger.valueOf(46)));
System.out.println("eea(65, 40) = " + apply(BigInteger.valueOf(65), BigInteger.valueOf(40)));
System.out.println("eea(1239, 735) = " + apply(BigInteger.valueOf(1239), BigInteger.valueOf(735)));
}
/*
* extended_euclid(d,s)
if s = 0
than return (d,1,0)
(d',s',t') <-- extended_euclid(s, d mod s)
return (d',t',s' - (d div s)t')
*/
public static Triple apply(final BigInteger a, final BigInteger b) {
if (b.equals(BigInteger.ZERO)) {
return new Triple(a, BigInteger.ONE, BigInteger.ZERO);
} else {
final Triple extension = apply(b, a.mod(b));
return new Triple(extension.d, extension.t, extension.s.subtract(a.divide(b).multiply(extension.t)));
}
}
private static class Triple {
public final BigInteger d;
public final BigInteger s;
public final BigInteger t;
private Triple(final BigInteger d, final BigInteger s, final BigInteger t) {
this.d = d;
this.s = s;
this.t = t;
}
#Override
public String toString() {
return "Triple{" +
"d=" + d +
", s=" + s +
", t=" + t +
'}';
}
}
}
eea(240, 46) = Triple{d=2, s=-9, t=47}
eea(65, 40) = Triple{d=5, s=-3, t=5}
eea(1239, 735) = Triple{d=21, s=-16, t=27}
I validated the response values from Wikipedia and here.

Converting double to fraction using BigInteger [duplicate]

This question already has answers here:
How do I print my Java object without getting "SomeType#2f92e0f4"?
(13 answers)
Closed 7 years ago.
I'm learner of Java.
I'm trying to convert decimal to fraction using BigInteger in Rational class.
If I print the numerator and denominator, right output comes out.
However, when I add, subtract, multiply, and divide, some strange output come out.
For example when I inputs
3.25 -3
The output is
13 4
-3 1
RationalTest#14ae5a5
RationalTest#7f31245a
RationalTest#6d6f6e28
RationalTest#135fbaa4
What is wrong with my code? What is that hashcode?
I couldn't find out in the internet, so I need your help:<
import java.util.Scanner;
import java.math.*;
public class TestTest
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
RationalTest r1 = RationalTest.getFraction(sc.next());
RationalTest r2 = RationalTest.getFraction(sc.next());
//Test if the right numerator and denominator comes out
System.out.println(r1.getNumerator()+" "+r1.getDenominator());
System.out.println(r2.getNumerator()+" "+r2.getDenominator());
System.out.println(r1.add(r2));
System.out.println(r1.subtract(r2));
System.out.println(r1.multiply(r2));
System.out.println(r1.divide(r2));
}
}
class RationalTest extends Number implements Comparable<RationalTest>
{
private static final long serialVersionUID = 1L;
private BigInteger numerator = BigInteger.ZERO;
private BigInteger denominator = BigInteger.ONE;
public RationalTest()
{
this(BigInteger.ZERO, BigInteger.ONE);
}
//Find GCD of numerator and denominator
public RationalTest(BigInteger numerator, BigInteger denominator)
{
BigInteger gcd = gcd(numerator, denominator);
this.numerator = ((denominator.compareTo(BigInteger.ZERO)>0) ? new BigInteger("1"):new BigInteger("-1")).multiply(numerator.divide(gcd));
this.denominator = denominator.abs().divide(gcd);
}
//Converting decimal to fraction
public static RationalTest getFraction(String s)
{
int result=-1;
for(int i=0; i<s.length(); i++)
{
if(s.charAt(i)=='.')
{
result=1;
break;
}
else
result=0;
}
//If result=1, String s is a decimal
if(result==1)
{
double d = Double.parseDouble(s);
long num = (long) Math.floor(d); // Only the int part
double denom = d-num; // Only the decimal part
int digitDec = s.length()-1-s.indexOf('.');
long up = (int) (denom*Math.pow(10, digitDec)); // numerator of denom
long down = (int) Math.pow(10, digitDec); // denominator of denim
return new RationalTest(BigInteger.valueOf(down*num+up), BigInteger.valueOf(down));
}
//If result=0, String s is not a decimal
else
{
return new RationalTest(BigInteger.valueOf(Long.parseLong(s)), BigInteger.ONE);
}
}
private static BigInteger gcd(BigInteger n, BigInteger d)
{
BigInteger n1 = n.abs();
BigInteger n2 = d.abs();
BigInteger gcd = BigInteger.ONE;
for(BigInteger k=BigInteger.ONE; k.compareTo(n1)<=0 && k.compareTo(n2)<=0; k=k.add(BigInteger.ONE))
{
if(n1.mod(k).equals(BigInteger.ZERO) && n2.mod(k).equals(BigInteger.ZERO))
gcd = k;
}
return gcd;
}
public BigInteger getNumerator()
{
return numerator;
}
public BigInteger getDenominator()
{
return denominator;
}
public RationalTest add(RationalTest secondRationalTest)
{
BigInteger n = (numerator.multiply(secondRationalTest.getDenominator())).add(denominator.multiply(secondRationalTest.getNumerator()));
BigInteger d = denominator.multiply(secondRationalTest.getDenominator());
return new RationalTest(n, d);
}
public RationalTest subtract(RationalTest secondRationalTest)
{
BigInteger n = (numerator.multiply(secondRationalTest.getDenominator())).subtract(denominator.multiply(secondRationalTest.getNumerator()));
BigInteger d = denominator.multiply(secondRationalTest.getDenominator());
return new RationalTest(n, d);
}
public RationalTest multiply(RationalTest secondRationalTest)
{
BigInteger n = numerator.multiply(secondRationalTest.getNumerator());
BigInteger d = denominator.multiply(secondRationalTest.getDenominator());
return new RationalTest(n, d);
}
public RationalTest divide(RationalTest secondRationalTest)
{
BigInteger n = numerator.multiply(secondRationalTest.getDenominator());
BigInteger d = denominator.multiply(secondRationalTest.getNumerator());
return new RationalTest(n, d);
}
#Override
public boolean equals(Object other)
{
if((this.subtract((RationalTest)(other))).getNumerator().equals(BigInteger.ZERO))
return true;
else
return false;
}
#Override
public int intValue()
{
return (int)doubleValue();
}
#Override
public float floatValue()
{
return (float)doubleValue();
}
#Override
public double doubleValue()
{
double x = this.getNumerator().doubleValue();
double y = this.getDenominator().doubleValue();
return x/y;
}
#Override
public long longValue()
{
return (long)doubleValue();
}
#Override
public int compareTo(RationalTest o) {
if(this.subtract(o).getNumerator().compareTo(BigInteger.ZERO)>0)
return 1;
else if(this.subtract(o).getNumerator().compareTo(BigInteger.ZERO)<0)
return -1;
else
return 0;
}
}
Oh I found out that I have to return string using toString()..
Thanks for your help!

How to format number as Kb/Gb using Java? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Format file size as MB, GB etc
Using NumberFormat, I would like to have my numbers formatted as scientific multipliers. In other words, I would like to have the following formatting:
1024 should be formatted as 1K
1048576 should be formatted as 1G
And obviously other numbers should be expressed using k, G, and other multiples.
How can I do that ? Or do I need some Java library ?
Roughly, this should work. It needs some polishing regarding proper double formatting.
static String formatSize(double size) {
String finalQ = "";
for (String q: new String[] {"k", "M", "G"}) {
if (size < 1024) break;
finalQ = q;
size /= 1024;
}
return size + finalQ;
}
package com.shashi.mpoole;
public class MetricPrefix {
static int ONE_ZERO_TWO_FOUR = 1024;
static String SEPARATOR = " ";
enum SIZE
{
B, K, M, G, T, P, E, Z, Y;
// BYTE, KILO, MEGA, GIGA, TERA, PETA, EXA, ZETTA, YOTTA;
}
class Result
{
int number = 0;
SIZE size;
public Result setNumber(int number)
{
this.number = number;
return this;
}
public Result setSize(SIZE size)
{
this.size = size;
return this;
}
public String getValue()
{
return this.number + SEPARATOR + this.size;
}
}
public Result getResult(double howMuchBigger)
{
double bigNumber = howMuchBigger;
int index = 0;
while(howMuchBigger-ONE_ZERO_TWO_FOUR>0)
{
bigNumber = howMuchBigger;
howMuchBigger = howMuchBigger/ONE_ZERO_TWO_FOUR;
index++;
}
if(index == 0)
return new Result().setNumber((int) (bigNumber)).setSize(SIZE.values()[index]);
else
return new Result().setNumber((int) (bigNumber/ONE_ZERO_TWO_FOUR)).setSize(SIZE.values()[index]);
}
public static void main(String[] args) {
MetricPrefix j = new MetricPrefix();
System.out.println(j.getResult(56).getValue());
}
}
Maybe that? How to convert byte size into human readable format in java?

Categories