How to convert binary to decimal using BigInteger? - java

I am trying to print decimal number from binary number using BigInteger class.
I am using BigInteger(String val, int radix) constructor of BigInteger class to convert given binary value to decimal but it is printing the exact binary value which is passed in constructor.Waht is the error?
The code is as follows:
System.out.print("Ente the decimal number:");
s=String.valueOf(sc.nextInt());
BigInteger i=new BigInteger(s,10);
System.out.println(i);

Actually you are not printing the decimal value of binary number
The value which is printed is the exact decimal representation of String val
According to radix that you put in this statement it will act like this :
BigInteger i = new BigInteger("11101", 10); // 11101
11101 this output is actually decimal number not a binary number
In order to get the expected result you should change radix value to 2 after that it will print the decimal value of the binary number:
BigInteger i = new BigInteger("11101", 2);
System.out.println(i);
Output:
29

If you are trying to parse the input String as a binary, you should write:
BigInteger i=new BigInteger(s,2);
When you print it
System.out.println(i);
it will be displayed in decimal by default.
It doesn't make sense, however, to read the number as int and then convert to String and pass to BigInteger constructor, since that limits the range of numbers that would work.
try:
s = sc.nextLine();
BigInteger i=new BigInteger(s,2);
System.out.println(i);

To parse the input in binary, use Scanner.nextBigInteger() with a radix of 2:
System.out.print("Enter the decimal number:");
BigInteger i = sc.nextBigInteger(2);
System.out.println(i);
The output will be in decimal by default.

Related

Need help: Program to convert binary to decimals (Java)

I would like some help with my code. I'm doing a method to convert binary numbers to decimals. This is my code:
public double decimal(double number){
String num=(number+"");
char charac;
double n;
double cont=0;
double exp;
double res=0;
for(int i=num.length()-1;i>=0;i--){
charac=num.charAt(i);//obtains digits 1 by 1 and converts to char
n=(Character)charac;//converts the digit into a number (double)
exp=Math.pow(2, cont);//makes the exponential function to multiply to n
n=n*exp;//multiplies exponential with the digit
res+=n;//adds digit to accumulator
cont++;
}
return res;
}
the problem i'm having is that the numbers get all messed up for whatever reason, like n being assigned 48 in the first loop of the for cycle.
I tried using n as an Int instead and it seemed to be working well but at the second loop of the for cycle it was assigned -2 somehow and that ruined the addition.
Change
n=(Character)charac;
to use Character.digit(char, int) otherwise you get the ascii value (not the digit value)
n=Character.digit(charac, 10);
By assigning char to double, it is infact passing on the ASCII value of that digit e.g. 48 is returned for char 0.
I think this answer from How to convert binary string value to decimal will help you:
String c = "110010"; // as binary
int decimalValue = Integer.parseInt(c, 2);
System.out.println(decimalValue);
result: 50

Reading long binary numbers in java

I am trying to write a program which converts binary numbers into decimal, however as soon as I have a binary number which is bigger than 10 digits I get a java.lang.numberformatexception error. I was wondering how I should rewrite my code in order to handle binary numbers:
try{
//will throw an exception if the user's input contains a non-Integer
int inputNumber = Integer.parseInt(returnEnterNumber());
//when our user wants to convert from binary to decimal
if(binaryToDecimal.isSelected()){
//checks if number is binary
int checkNumber = inputNumber;
while (checkNumber != 0) {
if (checkNumber % 10 > 1) {
throw new InvalidBinaryException();
}
checkNumber = checkNumber / 10;
}
//converts from binary and outputs result
int n = Integer.parseInt(returnEnterNumber(), 2);
displayConvertedNumber(Integer.toString(n));
}
}
catch(Exception e) {
displayConvertedNumber("WRONG INPUT! - TRY again");
}
Edit: I understand why the code fails, seeing as how it takes the number as a decimal and overflows. I am not sure how to rewrite the code to take the input as a binary straight away.
That's not a valid way to check a binary number. You're converting to an int in base 10, then checking that each of the digits in base 10 is zero or one. The conversion itself will fail on long enough input strings, and if it doesn't the checking will fail as well.
You shouldn't be converting it all all, you should be checking the input string itself.
EDIT Actually you don't have to do anything. Integer.parseInt() will check it for you and throw NumberFormatException if the string isn't a number in the specified radix.
You are parsing your binary digit string as a decimal integer first. If it has more than 10 significant digits then its decimal interpretation is too big to fit in an int, so the decimal conversion fails.
When you are going to parse the digit string as a binary number, simply avoid first parsing it as a decimal one. For instance, most of what you posted could be reduced to this:
int inputNumber = Integer.parseInt(returnEnterNumber(),
binaryToDecimal.isSelected() ? 2 : 10);
Take a look at Integers MAX values:
public class MainClass {
public static void main(String[] arg) {
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
}
}
the output will be:
2147483647
-2147483648
This means that if you have more than 10 digits, you have exceeded the max number for the Integer data type.
Try Using BigInteger on your binary value or consider returning it as String
Here is one line of code that will accomplish what you are looking for
System.out.println(new BigInteger("10101010101010111101010101001101010101010101001010101010101001011101010101010101",2).toString());

Split number into an integer and decimal

Input 23.893 would become INTEGER - 23, DECIMAL - 0.893
Here's the key snippet from my code
double realNumber = scan.nextDouble(); \\store the keyboard input in variable realNumber
double integerPart = Math.floor(realNumber); \\round down eg. 23.893 --> 23
double fractionPart = realNumber - integerPart; \\find the remaining decimal
When I try this with long numbers the decimal part differs slightly from the actual.
Input - 234.324112341234134 becomes INTEGER - 234.0,
DECIMAL - 0.3241123412341267
As stated by #dasblinkenlight you can use methods from BigDecimal and combine them with a splitter. I wouldn't count the decimal points though, easier to stick with BigDecimal.
For example:
public static void main(String[] args) {
String realNumber = "234.324823783782";
String[] mySplit = realNumber.split("\\.");
BigDecimal decimal = new BigDecimal(mySplit[0]);
BigDecimal real = new BigDecimal(realNumber);
BigDecimal fraction = real.subtract(decimal);
System.out.println(String.format("Decimal : %s\nFraction: %s", decimal.toString(),fraction.toString()));
}
This outputs the following:
Decimal : 234
Fraction: 0.324823783782
Your program's logic is correct. The problem is the representation that you have selected for your input.
double is inherently imprecise, so the lower-order digits are often not represented correctly. To fix this problem, you could use BigDecimal or even a String data type.
If you use BigDecimal, simply rewrite your algorithm using the methods of BigDecimal. If you use String, split user input at the decimal point, and add required zeros and decimal points after the whole part and before the fractional part.

How to prevent scientific display of a float?

I have the following output
output =4.08E-4
output =8.9E-5
output =0.978461
output =0.224577
Now the thing I don't get is for 4.08E-4 - I assume it is a negative exponential and given <0 it returns true but is there another way of displaying this in decimal format?
Most likely you are trying to print a float/double using System.out.println(...).
This eventually calls the public static String toString() method of Float (or Double). Either way, if you read the Javadoc it states:
If m is less than 10-3 or greater than or equal to 107, then it is
represented in so-called "computerized scientific notation." Let n be
the unique integer such that 10n <= m < 10n+1; then let a be the
mathematically exact quotient of m and 10n so that 1 <= a < 10. The
magnitude is then represented as the integer part of a, as a single
decimal digit, followed by '.' ('\u002E'), followed by decimal digits
representing the fractional part of a, followed by the letter 'E'
('\u0045'), followed by a representation of n as a decimal integer, as
produced by the method Integer.toString(int).
You can get around this using System.out.printf(), like this:
double d = 0.000408;
System.out.println(d);
System.out.printf("%f", d);
This prints:
4.08E-4
0,000408
My 2 cents.
System.out.println(4.08e-4);
0.000408
I use NumberFormat class-
double d = 0.000408;
//For considering 4 digits after decimal place
NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(4);
nf.setGroupingUsed(false);
System.out.println(d);
System.out.println(nf.format(d));
I think what you're looking for is either the class NumberFormat or the printf function, either one would work.

Java negative BigInteger toString

It seems I have a two's complement issue with Java's BigInteger.
I have a 64-bit integer where only the msb and the second msb are set to 1, the rest is 0.
In decimal this comes up to: -4611686018427387904
The Java side of my application receives this decimal number as a string, and converts it to BigInteger like so:
BigInteger bi = new BigInteger("-4611686018427387904", 10);
Then, it needs to display this number both in binary and hex forms.
I tried to use:
String bin = bi.toString(2);
String hex = bi.toString(16);
but I'm getting:
-100000000000000000000000000000000000000000000000000000000000000
-4000000000000000
whereas I expect to get:
1100000000000000000000000000000000000000000000000000000000000000
c000000000000000
Any tips?
Number always fits in 64 bits:
If your number always fits in 64 bits you can put it in a long and then print the bits / hex digits.
long l = bi.longValue();
String bin = Long.toBinaryString(l);
String hex = Long.toHexString(l);
System.out.println(bin);
System.out.println(hex);
Number may not always fit in 64 bits:
If the number does not always fit in 64 bits, you'll have to solve it "manually". To convert a number to it's two's complement representation you do the following:
If number is positive, do nothing
If number is negative:
Convert it to its absolute value
Complement the bits
Add 1
For a BigInteger the conversion looks as follows:
if (bi.compareTo(BigInteger.ZERO) < 0)
bi = bi.abs().not().add(BigInteger.ONE);
If you print it using bi.toString(2) you'll still get the sign character, instead of a leading 1. This can be solved by simply appending .replace('-', '1') to the string.
There is a BigInteger.toByteArray() method, that returns two's complement representation of BigInteger as a byte[]. All you need is to print that array in hex or binary form:
byte[] bs = bi.toByteArray();
for (byte b: bs) {
System.out.print(String.format("%02X", 0xff & b));
}
The binary number 1100000000000000000000000000000000000000000000000000000000000000 is definitely a positive number, right. It's equal to 2^63 + 2^62.
I don't see why you'd expect a negative number to become positive when you convert to base 2 or base 16.
You are confusing the base n representation with the internal representation of numbers.
If the number is 64 bits or less, then the simple way to solve this is to convert to a long and then use Long.toHexString().
what you mean?
Do you want to get Two's complement?
if you mean that, maybe i can give you an example
import java.util.*;
public class TestBina{
static void printBinaryInt(int i){
System.out.println("int:"+i+",binary:");
System.out.print(" ");
for(int j=31;j>=0;j--)
if(((1<<j)&i)!=0)
System.out.print("1");
else
System.out.print("0");
System.out.println();
}
public static void main(String [] args){
Random rand = new Random();
int i = rand.nextInt();
int j = rand.nextInt();
printBinaryInt(i);
printBinaryInt(j);
printBinaryInt(10);
printBinaryInt(-10);
}
}

Categories

Resources