I'm trying to convert an base 10 number to a base 2 and back to base 10. It works only for positive argument_decimal
argument_binary = Integer.toBinaryString(argument_decimal);
back_converted_argument_decimal = Integer.valueOf(argument_binary, 2);
For argument_decimal beeing negative, I get "java.lang.NumberFormatException: For input string: "11111111111111111111111111111111""
EDIT: here is what I do:
latitude_binary = Integer.toBinaryString((int)(latitude_decimal * 1000000));
back_converted_latitude_decimal = Long.parseLong(latitude_binary, 2) / 1000000.0;
which gives me bad results like -1.1 being forth and back converted to 4293.867296
Try to go via a long:
String binary = Integer.toBinaryString(-1);
long l = Long.parseLong(binary, 2);
int i = (int) l;
Tested, and working.
Why this works is because -1 is represented as a sequence of 32 bits 1 in system memory. When using the toBinaryString method, it creates a string using that exact representation. But, 32 bits of one is in fact equal to 2^32 - 1. That is too large for an int (4 bytes), because an int goes from [-2^31, 2^31-1]. This is because the most left bit is representing the sign. So to fix that overflow, first interpret that sequence of 1 and 0 characters as a Long. A long will do because the maximum value for a long is 2^63-1. Then convert the long to an int. This is done by simply taking the lower 32 bits.
The bug in your code is that you didn't cast the Long.parseLong to an int. So this should work:
lat_bin = Integer.toBinaryString((int)(lat_dec * 1000000));
lat_dec_conv = ((int) Long.parseLong(lat_bin, 2)) / 1000000.0;
public static void convertStringToDecimal(String binary) {
int decimal = 0;
int power = 0;
if (binary.charAt(0) == '1' && binary.length() == 32) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < binary.length(); i++) {
builder.append((binary.charAt(i) == '1' ? '0' : '1'));
}
while (binary.length() > 0) {
int temp = Integer
.parseInt(builder.charAt((binary.length()) - 1)+"");
decimal += temp * Math.pow(2, power++);
binary = binary.substring(0, binary.length() - 1);
}
System.out.println((decimal + 1) * (-1));
} else {
while (binary.length() > 0) {
int temp = Integer
.parseInt(binary.charAt((binary.length()) - 1) + "");
decimal += temp * Math.pow(2, power++);
binary = binary.substring(0, binary.length() - 1);
}
System.out.println(decimal);
}
}
Related
I am writing a program where I have strings of 9 bits of "0" and "1" to convert to exponent (taking each index and doing 2 ^ n from right to left).
example: ["1","0","1"] = 2^2 + 0^1 + 2^0
I know this is wrong because of the errors I am getting but am confused what to do which will calculate it in an efficient manner.
expoBefore = (strNum.charAt(9)) * 1 + (strNum.charAt(8)) * 2 + (strNum.charAt(7)) * 4 + (strNum.charAt(6)) * 8 + (strNum.charAt(5)) * 16 + (strNum.charAt(4)) * 32 + (strNum.charAt(3)) * 64 + (strNum.charAt(8)) * 128;
for example for one of the strings I am passing through [11111111] I want it to add 1 * 2^0 + 1 * 2 ^1 + 1 * 2^2.....etc
Clarification edit:
What is a more efficient way of converting a string of 0's and 1's to an integer?
You're trying to multiply a character's ascii value with an integer.
You must take the integer value of this character and then multiply it with another integer. Hope this helps.
String str = "111";
int x = Character.getNumericValue(str.charAt(0));
int y = Character.getNumericValue(str.charAt(1));
int z = Character.getNumericValue(str.charAt(2));
System.out.println(x + y + z);
Output:
3
You need to use a loop.
Iterate over the binary string. For each character, add 2^x to an accumulator if the bit is set (where x is the position of the bit), otherwise, add 0.
String binary = "11111111";
int number = 0;
for(int i = binary.length() - 1; i >= 0; i--) {
char c = binary.charAt(i);
number += Integer.parseInt(c + "") * Math.pow(2, binary.length() - i - 1);
}
System.out.println(number); // prints 255
How to convert binary to decimal
Just use a for loop and increment down to miniplate each number
It is very inefficient to use Math.pow(2, i) in a loop.
Faster to keep the previous value and multiply by 2 each time through (code untested):
int ip = 1;
int sum = 0;
for ( int i = binary.length -1; i >= 0) {
if ( binary.charAt(i) == '1' ) {
sum += ip;
}
ip *= 2;
}
You may want to use long ints if the number gets large.
Also, be sure to check that binary contains only zeroes and ones.
I am trying to add two binary numbers and then get their sum in binary system. I got their sum in decimal and now I am trying to turn it into binary. But there is problem that when I take their sum (in decimal) and divide by 2 and find remainders(in while loop), I need to put remainders into array in order print its reverse. However, there is an error in array part. Do you have any suggestions with my code? Thanks in advance.
Here is my code:
import java.util.Scanner;
public class ex1 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int m = scan.nextInt();
int k = dec1(n)+dec2(m);
int i=0,c;
int[] arr= {};
while(k>0) {
c = k % 2;
k = k / 2;
arr[i++]=c; //The problem is here. It shows some //error
}
while (i >= 0) {
System.out.print(arr[i--]);
}
}
public static int dec1(int n) {
int a,i=0;
int dec1 = 0;
while(n>0) {
a=n%10;
n=n/10;
dec1= dec1 + (int) (a * Math.pow(2, i));
i++;
}
return dec1;
}
public static int dec2(int m) {
int b,j=0;
int dec2 = 0;
while(m>0) {
b=m%10;
m=m/10;
dec2= dec2 + (int) (b * Math.pow(2, j));
j++;
}
return dec2;
}
}
Here:
int[] arr= {};
creates an empty array. Arrays don't grow dynamically in Java. So any attempt to access any index of arr will result in an ArrayIndexOutOfBounds exception. Because empty arrays have no "index in bounds" at all.
So:
first ask the user for the count of numbers he wants to enter
then go like: int[] arr = new int[targetCountProvidedByUser];
The "more" real answer would be to use List<Integer> numbersFromUsers = new ArrayList<>(); as such Collection classes allow for dynamic adding/removing of elements. But for a Java newbie, you better learn how to deal with arrays first.
Why are you using two different methods to do the same conversion? All you need is one.
You could have done this in the main method.
int k = dec1(n)+dec1(m);
Instead of using Math.pow which returns a double and needs to be cast, another alternative is the following:
int dec = 0;
int mult = 1;
int bin = 10110110; // 128 + 48 + 6 = 182.
while (bin > 0) {
// get the right most bit
int bit = (bin % 10);
// validate
if (bit < 0 || bit > 1) {
throw new IllegalArgumentException("Not a binary number");
}
// Sum up each product, multiplied by a running power of 2.
// this is required since bits are taken from the right.
dec = dec + mult * bit;
bin /= 10;
mult *= 2; // next power of 2
}
System.out.println(dec); // prints 182
An alternative to that is to use a String to represent the binary number and take the bits from the left (high order position).
String bin1 = "10110110";
int dec1 = 0;
// Iterate over the characters, left to right (high to low)
for (char b : bin1.toCharArray()) {
// convert to a integer by subtracting off character '0'.
int bit = b - '0';
// validate
if (bit < 0 || bit > 1) {
throw new IllegalArgumentException("Not a binary number");
}
// going left to right, first multiply by 2 and then add the bit
// Each time thru, the sum will be multiplied by 2 which shifts everything left
// one bit.
dec1 = dec1 * 2 + bit;
}
System.out.println(dec1); // prints 182
One possible way to display the result in binary is to use a StringBuilder and simply insert the converted bits to characters.
public static String toBin(int dec) {
StringBuilder sb = new StringBuilder();
while (dec > 0) {
// by inserting at 0, the bits end up in
// correct order. Adding '0' to the low order
// bit of dec converts to a character.
sb.insert(0, (char) ((dec & 1) + '0'));
// shift right for next bit to convert.
dec >>= 1;
}
return sb.toString();
}
This question already has answers here:
Java reverse an int value without using array
(33 answers)
Closed 3 years ago.
I'm a Java beginner so please pardon me if the question seems silly but I already searched the forums but it seems like no one has my problem.
I need to reverse the digits of an integer, and my class hasn't covered while or if loops yet, so I can't use those. All answers I can find on stackoverflow use those, so I can't use those.
the input I am given is below 10000 and above 0 and the code I have written has no problem reversing the integer if the input is 4 digits (e.g. 1000 - 9999) but once the input is between 1 - 999 it creates zeroes on the right hand side but according to the answer sheets its wrong.
For example: 1534 gets turned into 4351, but
403 becomes 3040 instead of the 304 it should be, and 4 becomes 4000 instead of 4.
I've tried different things in the code but it seems to just keep giving the same answer. Or maybe I'm just missing some key mathematics, I'm not sure.
Scanner scan = new Scanner(System.in);
System.out.println ("Enter an integer:");
int value = scan.nextInt();
int digit = (value % 10);
value = (value / 10);
int digit2 = (value % 10);
value = (value / 10);
int digit3 = (value % 10);
value = (value / 10);
int digit4 = (value % 10);
String reversednum = ("" + digit + digit2 + digit3 + digit4);
System.out.println ( reversednum);
and
Scanner scan = new Scanner(System.in);
System.out.println ("Enter an integer:");
int value = scan.nextInt();
int digit = (value % 10);
int reversednum = (digit);
value = (value /10);
digit = (value % 10);
reversednum = (reversednum * 10 + digit);
value = (value / 10);
digit = (value % 10);
reversednum = (reversednum * 10 + digit);
value = (value / 10);
digit = (value);
reversednum = (reversednum * 10 + digit);
System.out.println (reversednum);
What am I doing wrong?
You can convert from int to String -> reverse String -> convert again in int.
This is a code example.
public int getReverseInt(int value) {
String revertedStr = new StringBuilder(value).reverse().toString();
return Integer.parseInt(revertedStr);
}
Your code assumes that the number can be divided by 1000, which is clearly not the case for numbers below 1000. So add some if statements:
public int reverseNumber(int n) {
// step one: we find the factors using integer maths
int s = n;
int thousands = s / 1000; // this will be 0 if the number is <1000
s = s - thousands*1000;
int hundreds = s / 100; // this will be 0 if the number is <100
s = s - hundreds*100;
int tens = s / 10; // etc.
s = s - tens*10;
int ones = s;
// then: let's start reversing. single digit?
if (n<10) return n;
// two digits?
if (n<100) {
return ones*10 + tens;
}
// etc.
if (n<1000) {
return ones*100 + tens*10 + hundreds;
}
if (n<10000) {
return ones*1000 + tens*100 + hundreds*10 + thousands;
}
// if we get here, we have no idea what to do with this number.
return n;
}
Without spoon-feeding you code (leaving the value of writing your own homework code intact)...
Although you've said you can't use a loop, I don't think there's a sane approach that doesn't use one. Your basic problem is you have hard-coded a solution that works when the number happens to have 4 digits, rather than using code that adapts to a variable length. ie, are not using a loop.
All is not lost with your code however. You have figured out the essence of the solution. You just need to convert it to work processing one digit at a time. Consider using recursion, that divides the number by 10 each time and continues until the number is zero. Of course, you’ll have to capture the end digit before it’s lost by division.
Pseudo code may look like:
pass in the number and the current result
if the number is 0 return result
multiply result by 10 and add remainder of number divided by 10
return the result of calling self with number divided by 10 and result
then call this passing number and zero
Using modulus and division:
int nbr = 123; // reverse to 321 or 3*10*10 + 2*10 + 1
int rev = 0;
while(nbr > 0) {
rev *= 10; // shift left 1 digit
int temp = nbr % 10; // get LO digit
rev += temp; // add in next digit
nbr /= 10; // move to next digit
}
Or a recursive method:
public static int reverseInt(int number, int value) {
switch(number) { // is this conditional statement allowed???
case 0:
return value;
}
value *= 10;
int lod = number % 10;
value += lod;
number /= 10;
return reverseInt(number, value);
}
I need to add two binary numbers and return the sum. No base conversions are allowed. I know the long method, using arrays. But is there anything shorter ? And by shorter I mean "having smaller code length". Thanks in advance.
In case I was not explicit enough, here is an example:
Input:
1101
11
Output: 10000
The sum of two (binary) integers a and b can be computed as a+b, because all arithmetic is done in binary.
If your input is in human readable strings rather than binary, you can compute their sum in binary using the standard BigInteger class:
import java.math.BigInteger;
String sum(String a, String b) {
return new BigInteger(a, 2).add(new BigInteger(b, 2)).toString(2);
}
Represent the binary numbers as two strings. Reverse the two strings. Then, you can iterate along both strings simultaneously, adding values to three arrays, two which represent the binary digit being added from the strings and the third to represent the carry digit. Create a fourth array representing the answer (you might have to find the limit for how long the answer can possibly be).
fill the answer array by using standard binary adding:
0 + 0 = 0 in the same position,
1 + 0 = 0 + 1 = 1 in the same position,
1 + 1 = 0 in the same position, and carry a 1 to the next position,
1 + 1 + 1 = 1 in the same position, and carry a 1 to the next position.
Reverse the array and you'll have the answer as a binary number.
Here are a couple options, not using any utility methods provided by Java. These don't account for sign (leading +/-) so they only handle whole numbers.
This first method converts the binary strings to integers, adds the integers, then converts the result back to binary. It uses a method-local inner class Convert to avoid duplicating the binaryToInt() code for each of the parameters.
static String binaryAdd1(String binary1, String binary2) {
class Convert {
int binaryToInt(String binary) {
int result = 0;
for (int i = 0; i < binary.length(); i++) {
char c = binary.charAt(i);
result *= 2;
if (c == '1') {
result++;
} else if (c != '0') {
throw new IllegalArgumentException(binary);
}
}
return result;
}
}
final Convert convert = new Convert();
int int1 = convert.binaryToInt(binary1);
int int2 = convert.binaryToInt(binary2);
String result = "";
int temp = int1 + int2;
do {
result = ((temp & 1) == 1 ? '1' : '0') + result;
temp >>= 1;
} while (temp > 0);
return result;
}
This second method uses binary addition logic, as specified by JHaps in his answer, to directly add together the two parameters. No intermediate conversion to integers here.
static String binaryAdd2(String binary1, String binary2) {
final String validDigits = "01";
String binarySum = "";
// pad the binary strings with one more significant digit for carrying
String bin1 = '0' + binary1;
String bin2 = '0' + binary2;
// add them together starting from least significant digit
int index1 = bin1.length() - 1;
int index2 = bin2.length() - 1;
boolean carry = false;
while (index1 >= 0 || index2 >= 0) {
char char1 = bin1.charAt(index1 >= 0 ? index1 : 0);
char char2 = bin2.charAt(index2 >= 0 ? index2 : 0);
if (validDigits.indexOf(char1) < 0)
throw new NumberFormatException(binary1);
if (validDigits.indexOf(char2) < 0)
throw new NumberFormatException(binary2);
if (char1 == char2) {
binarySum = (carry ? '1' : '0') + binarySum;
carry = char1 == '1';
} else {
binarySum = (carry ? '0' : '1') + binarySum;
}
index1--;
index2--;
}
if (binarySum.length() > 1 && binarySum.charAt(0) == '0') {
binarySum = binarySum.substring(1);
}
String result = binarySum.toString();
return result;
}
Assume my system as 32 bit machine. Considering this if I use long int for n>63 I will get my value as 0. How to solve it?
double is perfectly capable of storing powers of two up to 1023 exactly. Don't let someone tell you that floating point numbers are somehow always inexact. This is a special case where they aren't!
double x = 1.0;
for (int n = 0; n <= 200; ++n)
{
printf("2^%d = %.0f\n", n, x);
x *= 2.0;
}
Some output of the program:
2^0 = 1
2^1 = 2
2^2 = 4
2^3 = 8
2^4 = 16
...
2^196 = 100433627766186892221372630771322662657637687111424552206336
2^197 = 200867255532373784442745261542645325315275374222849104412672
2^198 = 401734511064747568885490523085290650630550748445698208825344
2^199 = 803469022129495137770981046170581301261101496891396417650688
2^200 = 1606938044258990275541962092341162602522202993782792835301376
Just wait around for a 256-bit compiler, then use int :-)
No, seriously, since you just want to start with 1 and keep doubling, your best bet is to get a big integer library like GNU MP.
You would do that with a piece of code like (untested):
#include <stdio.h>
#include "gmp.h"
int main (void) {
int i;
mpz_t num;
mpz_init_set_ui (num, 1);
for (i = 0; i <= 200; i++) {
printf ("2^%d = ", i);
mpz_out_str (NULL, 10, num);
printf ("\n");
mpz_mul_ui (num, num, 2);
}
return 0;
}
You could code up your own data structure of an array of longs with only two operations, double and print but I think it would be far easier to just use GMP.
If you do want to roll your own, have a look at this. It's a variation/simplification of some big integer libraries I've developed in the past:
#include <stdio.h>
#include <stdlib.h>
// Use 16-bit integer for maximum portability. You could adjust
// these values for larger (or smaller) data types. SZ is the
// number of segments in a number, ROLLOVER is the maximum
// value of a segment plus one (need to be less than the
// maximum value of your datatype divided by two. WIDTH is
// the width for printing (number of "0" characters in
// ROLLOVER).
#define SZ 20
#define ROLLOVER 10000
#define WIDTH 4
typedef struct {
int data[SZ];
} tNum;
// Create a number based on an integer. It allocates the segments
// then initialises all to zero except the last - that one is
// set to the passed-in integer.
static tNum *tNumCreate (int val) {
int i;
tNum *num = malloc (sizeof (tNum));
if (num == NULL) {
printf ("MEMORY ERROR\n");
exit (1);
}
for (i = 0; i < SZ - 1; i++) {
num->data[i] = 0;
}
num->data[SZ-1] = val;
}
// Destroy the number. Simple free operation.
static void tNumDestroy (tNum *num) {
free (num);
}
// Print the number. Ignores segments until the first non-zero
// one then prints it normally. All following segments are
// padded with zeros on the left to ensure number is correct.
// If no segments were printed, the number is zero so we just
// output "0". Then, no matter what, we output newline.
static void tNumPrint (tNum *num) {
int i, first;
for (first = 1, i = 0; i < SZ; i++) {
if (first) {
if (num->data[i] != 0) {
printf ("%d", num->data[i]);
first = 0;
}
} else {
printf ("%0*d", WIDTH, num->data[i]);
}
}
if (first) {
printf ("0");
}
printf ("\n");
}
// Double a number. Simplified form of add with carry. Carry is
// initialised to zero then we work with the segments from right
// to left. We double each one and add the current carry. If
// there's overflow, we adjust for it and set carry to 1, else
// carry is set to 0. If there's carry at the end, then we have
// arithmetic overflow.
static void tNumDouble (tNum *num) {
int i, carry;
for (carry = 0, i = SZ - 1; i >= 0; i--) {
num->data[i] = num->data[i] * 2 + carry;
if (num->data[i] >= ROLLOVER) {
num->data[i] -= ROLLOVER;
carry = 1;
} else {
carry = 0;
}
}
if (carry == 1) {
printf ("OVERFLOW ERROR\n");
exit (1);
}
}
// Test program to output all powers of 2^n where n is in
// the range 0 to 200 inclusive.
int main (void) {
int i;
tNum *num = tNumCreate (1);
printf ("2^ 0 = ");
tNumPrint (num);
for (i = 1; i <= 200; i++) {
tNumDouble (num);
printf ("2^%3d = ", i);
tNumPrint (num);
}
tNumDestroy (num);
return 0;
}
and its associated output:
2^ 0 = 1
2^ 1 = 2
2^ 2 = 4
2^ 3 = 8
2^ 4 = 16
2^ 5 = 32
2^ 6 = 64
2^ 7 = 128
2^ 8 = 256
2^ 9 = 512
: : : : :
2^191 = 3138550867693340381917894711603833208051177722232017256448
2^192 = 6277101735386680763835789423207666416102355444464034512896
2^193 = 12554203470773361527671578846415332832204710888928069025792
2^194 = 25108406941546723055343157692830665664409421777856138051584
2^195 = 50216813883093446110686315385661331328818843555712276103168
2^196 = 100433627766186892221372630771322662657637687111424552206336
2^197 = 200867255532373784442745261542645325315275374222849104412672
2^198 = 401734511064747568885490523085290650630550748445698208825344
2^199 = 803469022129495137770981046170581301261101496891396417650688
2^200 = 1606938044258990275541962092341162602522202993782792835301376
python supports big integers out of the box. At any linux prompt, run this:
$ python -c "for power in range(201): print power, 2**power"
0 1
1 2
2 4
3 8
4 16
5 32
6 64
<snip>
196 100433627766186892221372630771322662657637687111424552206336
197 200867255532373784442745261542645325315275374222849104412672
198 401734511064747568885490523085290650630550748445698208825344
199 803469022129495137770981046170581301261101496891396417650688
200 1606938044258990275541962092341162602522202993782792835301376
This can be easily made into a script if necessary. See any python tutorial.
It's been ages since I've used Java seriously, but: BigInteger class? It has all the usual mathematical (multiply, pow) and bitwise (shiftLeft) operations.
Your tagging is a little confusing though, which language did you prefer?
Use java.math.BigInteger.shiftLeft.
for (int i = 0; i <= 200; i++) {
System.out.format("%d = %s%n", i, BigInteger.ONE.shiftLeft(i));
}
Excerpt of output:
0 = 1
1 = 2
2 = 4
3 = 8
4 = 16
:
197 = 200867255532373784442745261542645325315275374222849104412672
198 = 401734511064747568885490523085290650630550748445698208825344
199 = 803469022129495137770981046170581301261101496891396417650688
200 = 1606938044258990275541962092341162602522202993782792835301376
If BigInteger is unavailable, you can also just manually do the multiplication and store it in a String.
String s = "1";
for (int i = 0; i < 200; i++) {
StringBuilder sb = new StringBuilder();
int carry = 0;
for (char ch : s.toCharArray()) {
int d = Character.digit(ch, 10) * 2 + carry;
sb.append(d % 10);
carry = d / 10;
}
if (carry != 0) sb.append(carry);
s = sb.toString();
System.out.format("%d = %s%n", i + 1, sb.reverse());
}
(see full output)
In C/C++ I don't know of a standard way you can store integers that big, pax's solution is the rightway to go.
However for Java, you do have a way out, BigInteger
Use scheme!
1 => (expt 2 200)
1606938044258990275541962092341162602522202993782792835301376
in kotlin :
var x= readLine()!!.toInt()
var y=BigDecimal(1)
for (i in 1..x)
{
y *= BigDecimal(2)
}
println(DecimalFormat().format(y))
If unsigned long int is 64 bits then the largest value for 2^n that you can represent is 2^63 (i.e. n = 63):
unsigned long int x = (1UL << n); // n = 0..63