Bitwise not operation on a string of bits - java

I have a string with the value 0111000000. How can I perform a bitwise not operation on this string?
If I convert it to an integer, use the ~ operator and convert it back to a binary string, the resulting string has extra bits. I want the output to be exactly 1000111111.
The following code works fine, but it's not a good method. Is there another better way of doing this?
String bstr="";
while(m!=str.length())
{
char a=str.charAt(m);
if(a=='1')
{
a='0';
bstr=bstr+a;
m++;
}
else
{
a='1';
bstr=bstr+a;
m++;
}
}

try this
char[] a = s.toCharArray();
for(int i = 0; i < a.length; i++) {
a[i] = a[i]=='0' ? '1' : '0';
}
s = new String(a);
this also works fine
int i = ~Integer.parseInt(s, 2);
String tmp = Integer.toBinaryString(i);
s = tmp.substring(tmp.length()- s.length());

Keep track of how many bits there are in your bit-string. After converting to an integer and using a ~value operation to flip the bits, use a bit-mask to remove the unwanted 1 high-end bits.
Say for example your bit-string has a fixed 10 bits. Then you can mask off the unwanted high-end bits with: value & 0x2ff.
If the number of bits in the bit-string is variable:
value & ((1 << nBits) - 1)

StringUtils.replaceChars from common-lang might help here:
StringUtils.replaceChars("0111000000", "01", "10");

You should use string builder so you are able to change individual bits without creating many many garbage strings. Also you can flip single bits using XOR:
b ^= 1;
Which works on both binary and ASCII values of digits.

maybe this will work:
String result = Integer.toBinaryString(~(Integer.parseInt("0111000000",2)));
converts binary String to int, use bitwise not operator to invert, then convert back to binary string.

You can do this using XOR operation
public String xorOperation(String value) {
String str1 = value;
long l = Long.parseLong(str1, 2);
String str2 = "";
for (int i = 0; i < str1.length(); i++) {
str2 = str2 + "1";
}
long n = Long.parseLong(str2, 2);
long num = l ^ n;
String bininaryString = Long.toBinaryString(num);
System.out.println(bininaryString);
return bininaryString;
}

Related

Converting String binary to integer

How can I do this without using multiplication, division or mod?
I come with the solution but it needs multiplication.
public StringBToInt(String b) {
int value = 0;
for(int z = 0; z < b.length(); z++) {
value = value * 2 + (int)b.charAt(i) - 48;
}
}
EDIT: SORRY! Only 3 java API are allowed. length(), charAt(), and equals()
Without multiplication, use bitwise shift operator:
public StringBToInt(String b) {
int value = 0;
for(int z = 0; z < b.length(); z++) {
if(b.charAt(z) == '1'){
shift = b.length()-z-1;
value += (1 << shift);
}
}
}
Use the Integer.valueOf(String, int) method:
Integer.valueOf('10101',2)
Try to use Integer.parseInt(..) like this:
int value = Integer.parseInt(b, 2);
Ofcourse b is a binary String.
You can use the method Integer.parseInt to do this.
String binary = "101010"
int value = Integer.parseInt(binary, 2);
The '2' in Integer.parseInt means to parse the String in base 2.

Which is considered better to get the individual digits of a number? Divide-modulus or string charAt?

Approach 1:
Repeated Division-modulus operations.
long num = 123456789;
int count = 0;
while(num > 0)
{
int digit = num % 10;
if(digit == 1)
count ++;
num /= 10;
}
Approach 2:
Convert it into an String and get the characters at the position.
long num = 123456789;
int count = 0;
String s = String.valueOf(num);
for(int i = 0; i < s.length(); i++)
{
char ch = s.charAt(i);
if(ch == '1')
count ++;
}
The second operation doesn't need to get the remainder and the quotient each time. A charAt() method can be enough.
Which approach is considered to be better and why?
EDIT
Consider taking the input from the console.
1st Case:
long num = scanner.nextLong();
2nd Case:
String s = scanner.nextLine();
Here there would be no overhead on converting the number to string.
Also let us assume it is for positive numbers.
In this particular case, I'd say it's reasonable to use a string representation. After all, the count you're finding is less inherently about its numeric value than its decimal string representation - you'd get a different value if you converted it into hex instead.
For operations which are more base-neutral, I'd normally avoid performing a string conversion.
Note that you don't need a StringBuffer for your second approach. I'd use:
long num = 123456789;
int count = 0;
String text = String.valueOf(num);
for (int i = 0; i < text.length(); i++) {
char ch = text.charAt(i);
if (ch == '1') {
count++;
}
}
This is assuming performance is irrelevant, of course - which in my experience it usually is. Your first option will almost certainly be more efficient, as the second requires converting the number to a string first. But unless you need that efficiency, I'd stick with whatever code is simplest to understand - and in this case, I'd suggest that's the text-based representation.
(As an example of that: how confident are you that your first example works with negative numbers? How about the same question with your second example?)
I wrote a quick benchmark:
public static void main(String[] args) {
long num = 1657345918972817181L;
long time = System.nanoTime();
int i1 = byString(num);
long t1 = System.nanoTime() - time;
time = System.nanoTime();
int i2 = byNumber(num);
long t2 = System.nanoTime() - time;
System.out.println("Result: " + i1 + " Time: " + t1 + "ns");
System.out.println("Result: " + i2 + " Time: " + t2 + "ns");
}
static int byNumber(long num) {
int count = 0;
while (num > 0) {
long digit = num % 10;
if (digit == 1) {
count++;
}
num /= 10;
}
return count;
}
static int byString(long num) {
int count = 0;
String s = String.valueOf(num);
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (ch == '1') {
count++;
}
}
return count;
}
The result was as excepted:
Result: 5 Time: 18923ns
Result: 5 Time: 1924ns
The string representation need more time to compute. I tested this for larger and smaller numbers.
If I give a string to my methode byString(String num) I get these results:
Result: 5 Time: 5453ns
Result: 5 Time: 1924ns
It is faster, but avoiding the string method is still the better choice.
The first method is better.
To convert an integer to a string the String.valueOf function has to do the repeated divisions and modulus, that's the only possible way to convert from an integer to a base 10 string.
So the number of operations in method 1 is:
2N (N = length of the string)
while in method two it is higher, because after String.valueOf does its conversion you still have to get each individual character and handle it.
Converting a number to a string requires similar code as yours, but a string needs additional memory and some further processing, so your first idea is the better one.
The first one assuming you have the int in your lap.
It's almost certainly faster because it doesn't require a memory allocation operation and involves less code.
However in light of the edit where you might read an int or String from the console the answer would be to use what's in front of you.
In most realistic systems you would want to receive the input as a string at some point if only for input validation.
In that event dragging it into an int in order to unpack its digits back out is just unnecessary logic.

Convert a given decimal string into a binary string(even number of binary digits) in Java [duplicate]

for example, for 1, 2, 128, 256 the output can be (16 digits):
0000000000000001
0000000000000010
0000000010000000
0000000100000000
I tried
String.format("%16s", Integer.toBinaryString(1));
it puts spaces for left-padding:
` 1'
How to put 0s for padding. I couldn't find it in Formatter. Is there another way to do it?
P.S. this post describes how to format integers with left 0-padding, but it is not for the binary representation.
I think this is a suboptimal solution, but you could do
String.format("%16s", Integer.toBinaryString(1)).replace(' ', '0')
There is no binary conversion built into the java.util.Formatter, I would advise you to either use String.replace to replace space character with zeros, as in:
String.format("%16s", Integer.toBinaryString(1)).replace(" ", "0")
Or implement your own logic to convert integers to binary representation with added left padding somewhere along the lines given in this so.
Or if you really need to pass numbers to format, you can convert your binary representation to BigInteger and then format that with leading zeros, but this is very costly at runtime, as in:
String.format("%016d", new BigInteger(Integer.toBinaryString(1)))
Here a new answer for an old post.
To pad a binary value with leading zeros to a specific length, try this:
Integer.toBinaryString( (1 << len) | val ).substring( 1 )
If len = 4 and val = 1,
Integer.toBinaryString( (1 << len) | val )
returns the string "10001", then
"10001".substring( 1 )
discards the very first character. So we obtain what we want:
"0001"
If val is likely to be negative, rather try:
Integer.toBinaryString( (1 << len) | (val & ((1 << len) - 1)) ).substring( 1 )
You can use Apache Commons StringUtils. It offers methods for padding strings:
StringUtils.leftPad(Integer.toBinaryString(1), 16, '0');
I was trying all sorts of method calls that I haven't really used before to make this work, they worked with moderate success, until I thought of something that is so simple it just might work, and it did!
I'm sure it's been thought of before, not sure if it's any good for long string of binary codes but it works fine for 16Bit strings. Hope it helps!! (Note second piece of code is improved)
String binString = Integer.toBinaryString(256);
while (binString.length() < 16) { //pad with 16 0's
binString = "0" + binString;
}
Thanks to Will on helping improve this answer to make it work with out a loop.
This maybe a little clumsy but it works, please improve and comment back if you can....
binString = Integer.toBinaryString(256);
int length = 16 - binString.length();
char[] padArray = new char[length];
Arrays.fill(padArray, '0');
String padString = new String(padArray);
binString = padString + binString;
A simpler version of user3608934's idea "This is an old trick, create a string with 16 0's then append the trimmed binary string you got ":
private String toBinaryString32(int i) {
String binaryWithOutLeading0 = Integer.toBinaryString(i);
return "00000000000000000000000000000000"
.substring(binaryWithOutLeading0.length())
+ binaryWithOutLeading0;
}
I do not know "right" solution but I can suggest you a fast patch.
String.format("%16s", Integer.toBinaryString(1)).replace(" ", "0");
I have just tried it and saw that it works fine.
Starting with Java 11, you can use the repeat(...) method:
"0".repeat(Integer.numberOfLeadingZeros(i) - 16) + Integer.toBinaryString(i)
Or, if you need 32-bit representation of any integer:
"0".repeat(Integer.numberOfLeadingZeros(i != 0 ? i : 1)) + Integer.toBinaryString(i)
try...
String.format("%016d\n", Integer.parseInt(Integer.toBinaryString(256)));
I dont think this is the "correct" way to doing this... but it works :)
I would write my own util class with the method like below
public class NumberFormatUtils {
public static String longToBinString(long val) {
char[] buffer = new char[64];
Arrays.fill(buffer, '0');
for (int i = 0; i < 64; ++i) {
long mask = 1L << i;
if ((val & mask) == mask) {
buffer[63 - i] = '1';
}
}
return new String(buffer);
}
public static void main(String... args) {
long value = 0b0000000000000000000000000000000000000000000000000000000000000101L;
System.out.println(value);
System.out.println(Long.toBinaryString(value));
System.out.println(NumberFormatUtils.longToBinString(value));
}
}
Output:
5
101
0000000000000000000000000000000000000000000000000000000000000101
The same approach could be applied to any integral types. Pay attention to the type of mask
long mask = 1L << i;
A naive solution that work would be
String temp = Integer.toBinaryString(5);
while (temp.length() < Integer.SIZE) temp = "0"+temp; //pad leading zeros
temp = temp.substring(Integer.SIZE - Short.SIZE); //remove excess
One other method would be
String temp = Integer.toBinaryString((m | 0x80000000));
temp = temp.substring(Integer.SIZE - Short.SIZE);
This will produce a 16 bit string of the integer 5
// Below will handle proper sizes
public static String binaryString(int i) {
return String.format("%" + Integer.SIZE + "s", Integer.toBinaryString(i)).replace(' ', '0');
}
public static String binaryString(long i) {
return String.format("%" + Long.SIZE + "s", Long.toBinaryString(i)).replace(' ', '0');
}
This is an old trick, create a string with 16 0's then append the trimmed binary string you got from String.format("%s", Integer.toBinaryString(1)) and use the right-most 16 characters, lopping off any leading 0's. Better yet, make a function that lets you specify how long of a binary string you want. Of course there are probably a bazillion other ways to accomplish this including libraries, but I'm adding this post to help out a friend :)
public class BinaryPrinter {
public static void main(String[] args) {
System.out.format("%d in binary is %s\n", 1, binaryString(1, 4));
System.out.format("%d in binary is %s\n", 128, binaryString(128, 8));
System.out.format("%d in binary is %s\n", 256, binaryString(256, 16));
}
public static String binaryString( final int number, final int binaryDigits ) {
final String pattern = String.format( "%%0%dd", binaryDigits );
final String padding = String.format( pattern, 0 );
final String response = String.format( "%s%s", padding, Integer.toBinaryString(number) );
System.out.format( "\npattern = '%s'\npadding = '%s'\nresponse = '%s'\n\n", pattern, padding, response );
return response.substring( response.length() - binaryDigits );
}
}
This method converts an int to a String, length=bits. Either padded with 0s or with the most significant bits truncated.
static String toBitString( int x, int bits ){
String bitString = Integer.toBinaryString(x);
int size = bitString.length();
StringBuilder sb = new StringBuilder( bits );
if( bits > size ){
for( int i=0; i<bits-size; i++ )
sb.append('0');
sb.append( bitString );
}else
sb = sb.append( bitString.substring(size-bits, size) );
return sb.toString();
}
You can use lib https://github.com/kssource/BitSequence. It accept a number and return bynary string, padded and/or grouped.
String s = new BitSequence(2, 16).toBynaryString(ALIGN.RIGHT, GROUP.CONTINOUSLY));
return
0000000000000010
another examples:
[10, -20, 30]->00001010 11101100 00011110
i=-10->00000000000000000000000000001010
bi=10->1010
sh=10->00 0000 0000 1010
l=10->00000001 010
by=-10->1010
i=-10->bc->11111111 11111111 11111111 11110110
for(int i=0;i<n;i++)
{
for(int j=str[i].length();j<4;j++)
str[i]="0".concat(str[i]);
}
str[i].length() is length of number say 2 in binary is 01 which is length 2
change 4 to desired max length of number. This can be optimized to O(n).
by using continue.
import java.util.Scanner;
public class Q3{
public static void main(String[] args) {
Scanner scn=new Scanner(System.in);
System.out.println("Enter a number:");
int num=scn.nextInt();
int numB=Integer.parseInt(Integer.toBinaryString(num));
String strB=String.format("%08d",numB);//makes a 8 character code
if(num>=1 && num<=255){
System.out.println(strB);
}else{
System.out.println("Number should be in range between 1 and 255");
}
}
}

Why is it returning a negative value for a very long binary string?

public long bin_to_dec() {
int leng = a.length();
for (int i = 0, j = (leng - 1); i < leng; i++, j--) {
int number = Character.getNumericValue(a.charAt(j));
result = result + (number * ((long) Math.pow(2, i)));
}
return result;
}
This code takes a binary string as argument and return it's decimal value .
but for a long string i.e.
(111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111)
it returns -28 .
Why is the memory out of range?
or is my code is incorrect?
You are probably overrunning the length of an int. Integers in java are 32 bit and that binary string is 91 bits.
Try using something like BigInteger instead, which will not overflow. In fact, BigInteger has a built-in method for this:
BigInteger result = new BigInteger(a, 2);

From random integers to an actual String

This is a code that takes in an array of all the printing characters of the ASCII table. I am trying to make it so that any String message in the form of integers (e.g. String "aba" that is converted 97098097 can be put back into its original String form. 100101101 can be taken and made back into "dee". I've really tried hard with this method but it does not seem to be working, especially when it comes to numbers and such please help me. It is in Java by the way and I am using Eclipse.
public static String IntToString (){
int n = 0;
String message = "";
String message2 = null;
String [] ASCII = {" ","!","\"","#","$","%","&","\'","(",")","*","+",",","-",".","/","0","1","2","3","4","5","6","7","8","9",":",";","<","=",">","?","#","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","[","\\","]","^","_","`","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","{","|","}","~"};
String IntMessage = result.toString();
String firstChar = IntMessage.substring(0,2);
if (IntMessage.substring(0,1)=="1" && IntMessage.length()%3==0)
{
for (int x = (IntMessage.length() % 3 - 3) % 3; x < IntMessage.length()-2; x += 3)
n = Integer.parseInt(IntMessage.substring(Math.max(x, 0), x + 3));
message=message.concat(ASCII[n-31]);
return message;
}
else if (IntMessage.length()%3==2)
message2=ASCII[(Integer.parseInt(firstChar))-31];
for (int x = 2; x < IntMessage.length()-2; x += 3)
n = Integer.parseInt(IntMessage.substring(x, x + 3));
message=message2+=ASCII [n - 31];
return message;
It would seem that your encoding scheme is, er, crazy.
First, you take the ASCII value of a string, then take the character representation of that ASCII value, then store it as a string.
So "abc" => {97, 98, 99} => "979899".
But since you are using ASCII, which can have values of 100 or more, you are padding your ints with 0 if they are under 100:
"abc" => {97, 98, 99} => {"097", "098", "099"} => "097098099"
But you decide to do this only sometimes, because somehow
"aba" => "97098097"
That is, the first "a" is turned into "97", but the last "a" is turned into "097".
I'd say you should fix your encoding scheme first.
Also, these are hopefully not "random integers" because you are trying to turn them into sensible strings. Otherwise a simple mapping such as base64 would easily map any integers to strings, they just might not make much sense.
In fact, they aren't even really integers. You're storing your encoded strings as strings.
public static void main(String[] srgs){
String aaa = "100101101";
String[] a = split(aaa, 3);
String s = "";
for(int i=0;i<a.length;i++){
char c = (char)Integer.parseInt(a[i]);
s += Character.toString(c);
}
System.out.println(s);
}
public static String[] split(String str, int groupIndex){
int strLength = str.length();
int arrayLength = strLength/groupIndex;
String[] splitedArray = new String[strLength/groupIndex];
for(int i=0;i<arrayLength;i++){
String splitedStr = str.substring(0, groupIndex);
str = str.substring(groupIndex, str.length());
arrayLength = str.length();
splitedArray[i] = splitedStr;
}
return splitedArray;
}
The most important is that ASCII string covert to Char value, than turn it to real Character value in the string. The ASCII code length need be fix by 3 can be helpful in this case.

Categories

Resources