I am calculating the int equivalent of a given set of bits and storing that in memory. From there, I would like to determine all 1 value bits from the original bitmask. Example:
33 --> [1,6]
97 --> [1,6,7]
Ideas for an implementation in Java?
On BitSet
Use java.util.BitSet to store, well, a set of bits.
Here's how you can convert from an int to a BitSet, based on which bits in the int is set:
static BitSet fromInt(int num) {
BitSet bs = new BitSet();
for (int k = 0; k < Integer.SIZE; k++) {
if (((num >> k) & 1) == 1) {
bs.set(k);
}
}
return bs;
}
So now you can do the following:
System.out.println(fromInt(33)); // prints "{0, 5}"
System.out.println(fromInt(97)); // prints "{0, 5, 6}"
And just for completeness, here's the reverse transformation:
static int toInt(BitSet bs) {
int num = 0;
for (int k = -1; (k = bs.nextSetBit(k + 1)) != -1; ) {
num |= (1 << k);
}
return num;
}
So composing both together, we always get back the original number:
System.out.println(toInt(fromInt(33))); // prints "33"
System.out.println(toInt(fromInt(97))); // prints "97"
On 0-based indexing
Note that this uses 0-based indexing, which is the more commonly used indexing for bits (and most everything else in Java). This is also more correct. In the following, ^ denotes exponentiation:
33 = 2^0 + 2^5 = 1 + 32 97 = 2^0 + 2^5 + 2^6 = 1 + 32 + 64
33 -> {0, 5} 97 -> {0, 5, 6}
If you insist on using 1-based indexing, however, you can use bs.set(k+1); and (1 << (k-1)) in the above snippets. I would advise strongly against this recommendation, however.
Related questions
What does the ^ operator do in Java? -- it's actually not exponentiation
For bit fiddling, java.lang.Integer has some very helpful static methods. Try this code as a starting base for your problem:
public int[] extractBitNumbers(int value) {
// determine how many ones are in value
int bitCount = Integer.bitCount(value);
// allocate storage
int[] oneBits = new int[bitCount];
int putIndex = 0;
// loop until no more bits are set
while (value != 0) {
// find the number of the lowest set bit
int bitNo = Integer.numberOfTrailingZeros(value);
// store the bit number in array
oneBits[putIndex++] = bitNo+1;
// clear the bit we just processed from the value
value &= ~(1 << bitNo);
}
return oneBits;
}
I can show you C# implementation, Java should be very similar.
int value = 33;
int index = 1;
while (value > 0)
{
if ((value % 2) == 1)
Console.WriteLine(index);
index++;
value /= 2;
}
If you want to get an array like that you'll likely need to loop the number of bits you want to check & the integer with a bit shifted 1 for each step.
Something like (pseudo):
Init array
mask = 1
for (0 to BitCount):
if Integer & mask
array[] = pos
mask << 1
A bit-crunching variation would be something like:
int[] getBits(int value) {
int bitValue = 1;
int index = 1;
int[] bits = new int[33];
while (value >= bitValue)
{
bits[index++] = (value & bitValue);
bitValue << 1; // or: bitValue *= 2;
}
return bits;
}
Note that since the bits are indexed from 1 as you requested, bits[0] is left unused.
Related
To set bits, you use the OR operator. You can then use the AND operator to see which bits have been set:
long values = 0;
// Set bits
values |= (1L << 10);
values |= (1L << 45);
values |= (1L << 5600);
// Check if values are set
System.out.println(hasValue(values, 45)); // Returns true
System.out.println(hasValue(values, 55)); // Returns false
System.out.println(hasValue(values, 5600)); // Returns true
public static boolean hasValue(long data, int value)
{
return (((data >> value) & 1L) > 0);
}
Is it possible to loop through values and return each of the values originally set with the OR operator? The result printing:
Found value: 10
Found value: 45
Found value: 5600
Edit: Altered example to include larger numbers.
You could use your function inside of a loop from 0 to 64 to find everything like so:
for (int i = 0; i < 64; i++) {
if (hasValue(values, i))
System.out.println(“Found value: “ + i);
}
But I think there’s a better way. It’s destructive to the variable so if you want to save it for later do it before the loop but here it is:
for (int i = 0; i < 64 && values != 0; i++) {
if (values % 2 == 1)
System.out.println(“Found value: “ + i);
values = values >> 1;
}
The big advantage is to shift one bit at a time and not i bits every time needed.
I hope I understand question correctly. You just need to shift values by 1, and check youngest bit by AND 1 like that:
class Main {
public static void main(String args[]) {
long v = 0;
v |= (1L << 10);
v |= (1L << 45);
v |= (1L << 56);
int i = 0;
while(v != 0) {
if((v & 1L) == 1) {
System.out.println("Found value: " + i);
}
v = v >>> 1;
i++;
}
}
}
Java long has 64 bits.
So you could use 8 bits and store a maximum of 8 integers whose value is between 0 and 255 (unsigned).
You will need to use shift and then store.
So first unsigned byte will be 0-7 bits, second would be 8-15, third being 16-23 and so on.
But not otherwise.
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();
}
I have the following array of bytes:
01010110 01110100 00100101 01001011
These bytes are broken into two groups to encode seven integers. I know that the first group consists of 3 values 4 bits each (0101 0110 0111) that represent numbers 5,6,7. The second group consists of 4 values 5 bits each (01000 01001 01010 01011), which represent integers 8,9,10, and 11.
To extract the integers, I am currently using the following approach. Convert the array into a binary string:
public static String byteArrayToBinaryString(byte[] byteArray)
{
String[] arrayOfStrings = new String[byteArray.length];
for(int i=0; i<byteArray.length; i++)
{
arrayOfStrings[i] = byteToBinaryString(byteArray[i]);
}
String bitsetString = "";
for(String testArrayStringElement : arrayOfStrings)
{
bitsetString += testArrayStringElement;
}
return bitsetString;
}
// Taken from here: http://helpdesk.objects.com.au/java/converting-large-byte-array-to-binary-string
public static String byteToBinaryString(byte byteIn)
{
StringBuilder sb = new StringBuilder("00000000");
for (int bit = 0; bit < 8; bit++)
{
if (((byteIn >> bit) & 1) > 0)
{
sb.setCharAt(7 - bit, '1');
}
}
return sb.toString();
}
Then, I split the binary string into 2 substrings: 12 characters and 20 characters. Then I split each substring into new substrings, each of which has length that equals the number of bits. Then I convert each sub-substring into an integer.
It works but a byte array representing thousands of integers takes 30 seconds to a minute to extract.
I am a bit at a loss here. How do I do this using bitwise operators?
Thanks a lot!
I assume you have an understanding of the basic bit operations and how to express them in Java.
Use a pencil to draw a synthetic picture of the problem
byte 0 byte 1 byte 2 byte 3
01010110 01110100 00100101 01001011
\__/\__/ \__/\______/\___/\______/\___/
a b c d e f g
To extract a, b and c we need to do the following
a b c
byte 0 byte 0 byte 1
01010110 01010110 01110100
\. \. |||||||| \. \.
'\ '\ XXXX|||| '\ '\
0.. 0101 0.. 0110 0.. 0111
Shift And Shift
In Java
int a = byteArray[0] >>> 4, b = byteArray[0] & 0xf, c = byteArray[1] >>> 4;
The other values d, e, f and g are computed similarly but some of them require to read two bytes from the array (d and f actually).
d e
byte 1 byte 2 byte 2
01110100 00100101 00100101
||||\\\\ | |\\\\\
XXXX \\\\ | X \\\\\
\\\\| \\\\\
0.. 01000 01001
To compute d we need to isolate the least four bits of byte 1 with byteArray[1] & 0xf then make space for the bit from byte 2 with (byteArray[1] & 0xf) << 1, extract that bit with byteArray[1] >>> 7 and finally merge together the result.
int d = (byteArray[1] & 0xf) << 1 | byteArray[2] >>> 7;
int e = (byteArray[2] & 0x7c) >>> 2;
int f = (byteArray[2] & 0x3) << 3 | byteArray[3] >>> 5;
int g = byteArray[3] & 0x1f;
When you are comfortable with handling bits operations you may consider generalizing the function that extract the integers.
I made function int extract(byte[] bits, int[] sizes, int[] res), that given an array of bytes bits, an array of sizes sizes, where the even indices hold the size of the integers to extract in bits and the odd indices the number of integers to extract, and an output array res large enough to hold all the integers in output, extracts from bits all the integers expressed by sizes.
It returns the number of integers extracted.
For example the original problem can be solved as
int res[] = new int[8];
byte bits[] = new byte[]{0x56, 0x74, 0x25, 0x4b};
//Extract 3 integers of 4 bits and 4 integers of 5 bits
int ints = BitsExtractor.extract(bits, new int[]{4, 3, 5, 4}, res);
public class BitsExtractor
{
public static int extract(byte[] bits, int[] sizes, int[] res)
{
int currentByte = 0; //Index into the bits array
int intProduced = 0; //Number of ints produced so far
int bitsLeftInByte = 8; //How many bits left in the current byte
int howManyInts = 0; //Number of integers to extract
//Scan the sizes array two items at a time
for (int currentSize = 0; currentSize < sizes.length - 1; currentSize += 2)
{
//Size, in bits, of the integers to extract
int intSize = sizes[currentSize];
howManyInts += sizes[currentSize+1];
int temp = 0; //Temporary value of an integer
int sizeLeft = intSize; //How many bits left to extract
//Do until we have enough integer or we exhaust the bits array
while (intProduced < howManyInts && currentByte <= bits.length)
{
//How many bit we can extract from the current byte
int bitSize = Math.min(sizeLeft, bitsLeftInByte); //sizeLeft <= bitsLeftInByte ? sizeLeft : bitsLeftInByte;
//The value to mask out the number of bit extracted from
//The current byte (e.g. for 3 it is 7)
int byteMask = (1 << bitSize) - 1;
//Extract the new bits (Note that we extract starting from the
//RIGHT so we need to consider the bits left in the byte)
int newBits = (bits[currentByte] >>> (bitsLeftInByte - bitSize)) & byteMask;
//Create the new temporary value of the current integer by
//inserting the bits in the lowest positions
temp = temp << bitSize | newBits;
//"Remove" the bits processed from the byte
bitsLeftInByte -= bitSize;
//Is the byte has been exhausted, move to the next
if (bitsLeftInByte == 0)
{
bitsLeftInByte = 8;
currentByte++;
}
//"Remove" the bits processed from the size
sizeLeft -= bitSize;
//If we have extracted all the bits, save the integer
if (sizeLeft == 0)
{
res[intProduced++] = temp;
temp = 0;
sizeLeft = intSize;
}
}
}
return intProduced;
}
}
Well I did the first group , the second can be done in similar fashion
public static void main(String args[]) {
//an example 32 bits like your example
byte[] bytes = new byte[4];
bytes[0] = 31;//0001 1111
bytes[1] = 54;//0011 0110
bytes[2] = 67;
bytes[3] = 19;
//System.out.println(bytes[0]);
int x = 0;
int j = -1; // the byte number
int k = 0; // the bit number in that byte
int n = 0; // the place of the bit in the integer we are trying to read
for (int i = 0; i < 32; i++) {
if (i < 12) { //first group
if (i % 8 == 0) {
j++;
k = 0;
}
if (i % 4 == 0) {
x = 0;
n = 0;
}
byte bit = (byte) ((bytes[j] & (1 << (7 - k))) >> (7 - k));
System.out.println("j is :" + j + " k is :" + k + " " + bit);
x = x | bit << (3 - n);
if ((i + 1) % 4 == 0) {
System.out.println(x);
}
k++;
n++;
} else {
}
}
}
It's a bit tricky because you are trying to encode an integer on less than what java allocates (8 bits). So I had to take each bit and "construct" the int from them
To get each bit
byte bit = (byte) ((bytes[j] & (1 << (7 - k))) >> (7 - k));
this takes the byte we are at and does And operation. For example I want the 3rd bit of the 1st byte, I do
bytes[0] & 1 << (7 - 3)
but this gives me an integer encoded over 8 bits, so I still have to shift it to get that single bit with >> (7 - 3)
Then I just Or it with x (the int we are trying to decode). All while putting it at the right position with << (3 - n) . 3 because your integer is encoded over 4 bits
Try running the code and reading the output.
I am honestly not sure if this is the best way, but I believe it's at least faster than dealing with Strings
How to efficiently save and access a large array of 5 bit numbers in memory?
For example
01100
01101
01110
01111
10000
10001
which I will later convert to a byte to check what number it is?
I was thinking of just using an array of bytes but after a while this will be wasting a lot of memory as this will be a continually growing array. Also I will want to save this array efficiently. I will only be using exactly 5 bits.
This is the code that I use for a bit array implementation in C, in JAVA it's going to be the same, I must reconsider what I said about the list, maybe an array is going to be better.
Anyway, you consider the array as a contiguous segments of bits. Those functions set, get, and read the k-th bit of the array. In this case I'm using an array of integers, so you see '32', is you use an array of bytes, then you'd use '8'.
void set_bit(int a[], int k)
{
int i = k / 32;
int pos = k % 32;
unsigned int flag = 1; // flag = 0000....00001
flag = flag << pos; // flag = 0000...00100..0000
a[i] = a[i] | flag; // set the bit at the k-th position in a[i]
}
void clear_bit(int a[], int k)
{
int i = k / 32;
int pos = k % 32;
unsigned int flag = 1; // flag = 0000....00001
flag = flag << pos; // flag = 0000...00100..0000
flag = ~flag;
a[i] = a[i] & flag; // set the bit at the k-th position in a[i]
}
int test_bit(int a[], int k)
{
int i = k / 32;
int pos = k % 32;
unsigned int flag = 1; // flag = 0000....00001
flag = flag << pos; // flag = 0000...00100..0000
if (a[i] & flag) // test the k-th bit of a to be 1
return 1;
else
return 0;
}
I don't know how you store the five bits number, you'll have to insert them bit by bit, and also keep track of the last empty position in the bit array.
"I was thinking of just using an array of bytes but after a while this will be wasting a lot of memory as this will be a continually growing array."
I've dealt with a similar problem and decided to write a file based BitInputStream and a BitOutputSteam. Therefore running out of memory was no longer an issue. Please note that the given links are not my work but good examples of how to write a bit input/output stream.
I wrote an implementation of a 5-bit byte vector on top of an 8-bit byte vector in Javascript some time ago that might be of some help.
const ByteVector = require('bytevector');
class FiveBuffer {
constructor(buffer = [0], bitsAvailable = 8) {
this.buf = new ByteVector(buffer);
this.bitsAvailable = bitsAvailable;
this.size = Math.floor(((this.byteSize() * 8) - this.bitsAvailable) / 5);
}
push(num) {
if (num > 31 || num < 0)
throw new Error(`Only 5-bit unsigned integers (${num} not among them) are accepted`);
var firstShift = 5 - this.bitsAvailable;
var secondShift = this.bitsAvailable + 3;
var firstShifted = shiftRight(num, firstShift);
var backIdx = this.buf.length - 1;
var back = this.buf.get(backIdx);
this.buf.set(backIdx, back | firstShifted);
if (secondShift < 8) {
var secondShifted = num << secondShift;
this.buf.push(secondShifted);
}
this.bitsAvailable = secondShift % 8;
this.size++;
}
get(idx) {
if (idx > this.size)
throw new Error(`Index ${idx} is out of bounds for FiveBuffer of size ${this.size}`);
var bitIdx = idx * 5;
var byteIdx = Math.floor(bitIdx / 8);
var byte = this.buf.get(byteIdx);
var bit = bitIdx % 8;
var firstShift = 3 - bit;
var firstShifted = shiftRightDestroy(byte, firstShift);
var final = firstShifted;
var secondShift = 11 - bit;
if (secondShift < 8) {
var secondShifted = this.buf.get(byteIdx + 1) >> secondShift;
final = final | secondShifted;
}
return final;
}
buffer() {
this.buf.shrink_to_fit();
return this.buf.buffer();
}
debug() {
var arr = [];
this.buffer().forEach(x => arr.push(x.toString(2)));
console.log(arr);
}
byteSize() {
return this.buf.size();
}
}
function shiftRightDestroy(num, bits) {
var left = 3 - bits;
var res = (left > 0) ? ((num << left) % 256) >> left : num;
return shiftRight(res, bits);
}
function shiftRight(num, bits) {
return (bits < 0) ?
num << -bits :
num >> bits;
}
module.exports = FiveBuffer;
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