Java bitwise operations return "wrong" value - java

---EDIT: I am not allowed to use any packages, or prewirtten methods. And no worries, i don't want you to make my "homework", i just need a little hint!---
I found these interesting Algorithms. I want to use the method bitwiseAdd. My problem is, that the left shift operator returns a value that is not binary...
I understand the algorithm, but i am quite a beginner. So here is the "program". I implemented extra outputs to find the issue. I think it must be the left shift operator. Here is the code:
import java.io.BufferedReader;
import java.io.InputStreamReader;
class Addition1
{
public static int first;
public static int second;
public static void main(String args[]) throws Exception
{
BufferedReader userInput = new BufferedReader(newInputStreamReader(System.in));
System.out.println("Geben sie den ersten Summanden ein!");
first = Integer.parseInt(userInput.readLine());
System.out.println("Geben sie den zweiten Summanden ein!");
second = Integer.parseInt(userInput.readLine());
bitwiseAdd(first, second);
}
public static void bitwiseAdd(int n1, int n2)
{
int x = n1, y = n2;
int xor, and, temp;
and = x & y;
xor = x ^ y;
System.out.println("x: " + x);
System.out.println("y: " + y);
System.out.println("and: " + and);
System.out.println("xor: " + xor);
System.out.println("Schleife:");
while (and != 0)
{
and <<= 1;
System.out.println("and <<= 1: " + and);
temp = xor ^ and;
System.out.println("temp = xor ^ and: " + temp);
and &= xor;
System.out.println("and &= xor: " + and);
xor = temp;
System.out.println("xor = temp: " + xor);
}
System.out.println("Ergebnis: " + xor);
}
}
Here is the output (+annotations) of the program for n1= 1001 and n2=1101:
Geben sie den ersten Summanden ein! (means: type in first value)
1001
Geben sie den zweiten Summanden ein! (means: type in second value)
1101
x: 1001
y: 1101
and: 73 (java might interpret x and y as non binary)
xor: 1956
Schleife: (means: loop)
and <<= 1: 146
temp = xor ^ and: 1846
and &= xor: 128
xor = temp: 1846
and <<= 1: 256
temp = xor ^ and: 1590
and &= xor: 256
xor = temp: 1590
and <<= 1: 512
temp = xor ^ and: 1078
and &= xor: 512
xor = temp: 1078
and <<= 1: 1024
temp = xor ^ and: 54
and &= xor: 1024
xor = temp: 54
and <<= 1: 2048
temp = xor ^ and: 2102
and &= xor: 0
xor = temp: 2102
Ergebnis: 2102 (means: result)
I would be happy about any help! :)
Have a nice day,
Cortex

The values in your program were never interpreted as binary. You are actually adding the decimal values 1001 and 1101, and correctly summing them to 2102. Also, the binary representations of decimal 1001 and 1101 are
1001: 00000011 11101001
1101: 00000100 01001101
When anded, you get decimal 73:
73: 00000000 01001001
If you want to interpret those numbers as binary, use a radix of 2 in Integer.parseInt, for example:
first = Integer.parseInt(userInput.readLine(), 2);
To output a number in a binary format, use Integer.toBinaryString, for example:
System.out.println("Ergebnis: " + Integer.toBinaryString(xor));

You are trying to write a virtual machine inside a virtual machine inside the real machine, which might itself be a virtual machine. No wonder there is confusion.
You will need to represent you data as array of bool (or int or char etc).
bool [] operand1 = new bool [8];
bool [] operand2 = new bool [8];
bool [] leftShift (bool [] operand)
{
bool [] result = new bool [operand.length];
for (int i=8; i>1; i++)
{
result[i] = operand[i-1];
}
return result;
}
bool [] and (bool [] operand1, bool [] operand2)
{
int max, min;
if (operand1.length > operand2.length) {
max = operand1.length;
min = operand2.length;
}
else {
max = operand2.length;
min = operand1.length;
}
bool [] result = new bool [max];
for (int i = 0; i<min;i++)
{
result[i] = operand1[i] && operand2[i];
}
return result;
}

I used first = 1001; second = 1101; bitwiseAdd(first, second); in the main method, but still the program interprets these as decimal numbers (which is logical).
When you write a literal in a Java program, the syntax of the literal tells Java how to interpret it.
12345 // decimal
012345 // octal
0x1234 // hexadecimal
0b1001 // binary
There is no guesswork here. The syntax you use tells the Java compiler.
For more info: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
(The only slightly tricky thing is that a leading non-significant zero means that the number is octal not decimal. That is an regrettable (IMO) carry-over from the C programming language. It does trip up some people.)
Do you know how i can change that?
Yea ... if you want to express the numbers as binary in the source code, use binary literals.
The thing you need to get thoroughly into your head is that binary / octal / decimal / hexadecimal are all about getting numbers from or presenting numbers to the user (or programmer). Internally, they all turn into the same thing. The int type (and other integral types) are agnostic of decimal, binary and so on. There is only one type, and the arithmetic and bitwise operators on int have only one meaning.

Related

How to proceed to find the maximum sum of 2 integers with replacing only one digit?

example 1
a=1
b=90
answer will be 1+99 = 100
example 2
23
45
answer will be 93+45 =138
Note:there can be negative numbers also.
You are not allowed to add digits, just replace a single digit to get maximum sum
Use this
if(a>b || a==b){
a=10*((a/10)+1)
return a;
}
else{
b=10*((b/10)+1)
return b;
}
Let's assume that the first number has d1 digits, the second has d2 digits and for the sake of simplicity, let's assume further that
d1 >= d2
and
k = d1 - d2
so, k >= 0. If the first k digits of the larger number are modifiable (modifiable: if the number is positive, but the digit is not 9, or the number is negative), then modify that digit optimally, as described earlier.
Otherwise, in subsequent digits check whether any of the digits is modifiable and if so, compute the difference between the changes you would do on the two digits and choose the one where the change was larger.
When the first modification was done, then the work should stop.
Here is a straightforward recursion in JavaScript (easily translatable to Java or C++). The idea is to choose the best addition or subtraction (for negatives) possible for each number. The complexity is O(log10 n), where n is the larger number.
function improve(n){
if (n > -10 && n < 10)
return n < 0 ? -n : 9 - n;
return Math.max(
10 * improve(~~(n / 10)),
n < 10 ? -(n % 10) : 9 - (n % 10)
);
}
function f(a, b){
return a + b + Math.max(improve(a), improve(b));
}
var abs = [
[1, 90],
[23, 45],
[-94, 5]
];
for (let [a, b] of abs){
console.log(a, b);
console.log(f(a, b));
console.log('');
}
I had a rather simple idea. First convert two integers `n1`, `n2` into c-string `s1` , `s2`. Then if s1[0] = '-' (n1 is negative) change `s1[1] = 0`, else (n1>0) change `s1[0] = 9`. Similarly for c-string `s2`. Finally compare which sum is the larger: `n1 + stoi(s2)` or `n2 + stoi(s1)` to determine the set to be choose.
One extra care is that for a integer >0, and starting with digits`999...` To take this case into consideration, we use a for loop to change the first digit that is not equal to `9`. If all digits are `9`, we do nothing to the integer.
#include <iostream>
#include <fstream>
#include <cstring>
int main()
{
int n1, n2, a, b;
char s1[32], s2[32];
while (1)
{
std::cout << "\n input n1 & n2 = ";
std::cin >> n1 >> n2;
itoa(n1, s1, 10);
itoa(n2, s2, 10);
if (s1[0] == '-') s1[1] = '0';
else for (int i=0; i<strlen(s1); i++) {
if (s1[i] = '9') continue;
else {s1[i] = '9'; break;}
if (s2[0] == '-') s2[1] = '0';
else for (int i=0; i<strlen(s2); i++) {
if (s2[i] = '9') continue;
else {s2[i] = '9'; break;}
a = n1 + std::stoi(s2);
b = n2 + std::stoi(s1);
if (a > b) std::cout << "two integers: " << n1 << ", " << s2 <<std::endl;
else std::cout << "two integers: " << s1 << ", " << n2 <<std::endl;
}
return 0;
}
Some test sets:
$ ./a.exe
input n1 & n2 = 12 78
two integers: 92, 78
input n1 & n2 = -45 90
two integers: -05, 90
input n1 & n2 = -34 -78
two integers: -34, -08
input n1 & n2 = 23 9999
two integers: 93, 9999

How to convert a binary String to a decimal string in Java

I was working on a homework and thought I had finished but the teacher told me that it wasn't what he was looking for so I need to know how I can convert a binary number that is stored as a String to a decimal string without using any built-in function outside of length(), charAt(), power function, and floor/ceiling in Java.
This is what I had on the beginning.
import java.util.Scanner;
public class inclass2Fall15Second {
public static void convertBinaryToDecimalString() {
Scanner myscnr = new Scanner(System.in);
int decimal = 0;
String binary;
System.out.println("Please enter a binary number: ");
binary = myscnr.nextLine();
decimal = Integer.parseInt(binary, 2);
System.out.println("The decimal number that corresponds to " + binary + " is " + decimal);
}
public static void main (String[] args) {
convertBinaryToDecimalString();
}
}
To convert a base 2 (binary) representation to base 10 (decimal), multiply the value of each bit with 2^(bit position) and sum the values.
e.g. 1011 -> (1 * 2^0) + (1 * 2^1) + (0 * 2^2) + (1 * 2^3) = 1 + 2 + 0 + 8 = 11
Since binary is read from right-to-left (i.e. LSB (least significant bit) is on the rightmost bit and MSB (most-significant-bit) is the leftmost bit), we traverse the string in reverse order.
To get the bit value, subtract '0' from the char. This will subtract the ascii value of the character with the ascii value of '0', giving you the integer value of the bit.
To calculate 2^(bit position), we can keep a count of the bit position, and increment the count on each iteration. Then we can just do 1 << count to obtain the value for 2 ^ (bit position). Alternatively, you could do Math.pow(2, count) as well, but the former is more efficient, since its just a shift-left instruction.
Here's the code that implements the above:
public static int convertBinStrToInt(String binStr) {
int dec = 0, count = 0;
for (int i = binStr.length()-1; i >=0; i--) {
dec += (binStr.charAt(i) - '0') * (1 << count++);
}
return dec;
}

What does '<< ' mean ? And what this code mean?

I don't understand what is this doCalculatePi means or does, in the following example:
public static double doCalculatePi(final int sliceNr) {
final int from = sliceNr * 10;
final int to = from + 10;
final int c = (to << 1) + 1;
double acc = 0;
for (int a = 4 - ((from & 1) << 3), b = (from << 1) + 1; b < c; a = -a, b += 2) {
acc += ((double) a) / b;
}
return acc;
}
public static void main(String args[]){
System.out.println(doCalculatePi(1));
System.out.println(doCalculatePi(2));
System.out.println(doCalculatePi(3));
System.out.println(doCalculatePi(4));
System.out.println(doCalculatePi(10));
System.out.println(doCalculatePi(100));
}
I have printed the values to understand what the results are but I still have no clue what this code calculates. The conditions inside the loop are not clear.
<< means left shift operation, which shifts the left-hand operand left by the number of bits specified by the right-hand operand (See oracle docs).
Say, you have a decimal value, 5 which binary representation is 101
Now for simplicity, consider,
byte a = (byte)0x05;
Hence, the bit representation of a will be,
a = 00000101 // 1 byte is 8 bit
Now if you left shift a by 2, then a will be
a << 2
a = 00010100 //shifted place filled with zero/s
So, you may now understand that, left shift a by 3 means
a << 3
a = 00101000
For better understanding you need to study Bitwise operation.
Note, you are using int instead of byte, and by default, the int data type is a 32-bit signed integer (reference here), so you have to consider,
int a = 5;
in binary
a << 3
a = 00000000 00000000 00000000 00101000 // total 32 bit
My guess is that it approximates PI with
PI = doCalculatePi(0)+doCalculatePi(1)+doCalculatePi(2)+...
Just a guess.
Trying this
double d = 0;
for(int k = 0; k<1000; k++) {
System.out.println(d += doCalculatePi(k));
}
gives me
3.0418396189294032
3.09162380666784
3.1082685666989476
[...]
3.1414924531892394
3.14149255348994
3.1414926535900394
<< is the Bitshift operator.
Basically, every number is represented as a series of binary digits (0's and 1's), and you're shifting each of those digits to the left by however many places you indicate. So for example, 15 is 00001111 and 15 << 1 is 00011110 (or 30), while 15 << 2 is (00111100) which is 60.
There's some special handling that comes into play when you get to the sign bit, but you should get the point.

Bit shifting exercise

The task is to read an integer from keyboard, convert it into 8 groups of 4 bits, then convert each bit into a hex number and output them one after one. This must be done by using bit shifting, no other solution counts.
My idea was to use a mask with 4 ones to select the group of bits, then shift that group right, removing preceding zeroes, and output the number in hex.
Here's how I tried to approach this:
public static void main(String args[]) {
Scanner input = new Scanner(System.in);
System.out.print("Enter an integer: ");
int x = input.nextInt();
System.out.println("Binary representation: " + Integer.toBinaryString(x));
System.out.println("Hexadecimal representatio1n: " + Integer.toHexString(x));
int mask = 15 << 28;
System.out.println(Integer.toBinaryString(mask));
int k = 28;
for (int i = 1; i <= 8; i++)
{
int result = mask & x;
//System.out.println(Integer.toBinaryString(result));
result = x >>> k ;
mask = mask >> 4;
k = k - 4;
System.out.println(Integer.toHexString(result));
}
}
Sample output:
Enter an integer: 324234234
Binary representation: 10011010100110110101111111010
Hexadecimal representatio1n: 13536bfa
11110000000000000000000000000000
1
13
135
1353
13536
13536b
13536bf
13536bfa
Why is it not working correctly?
Thanks.
Your when you shift the result variable, you aren't shifting by the result, you are shifting it by x
if you change it to
result = result >>> k;
it should work
on a side note, this problem is much easier done the other way(from the least significant bit to the most significant bit)
like
int x = 0xaabcdabcd;
int mask = 0x0fffffff;
for(int i =0;i < 8; i ++){
System.out.println(x & mask);
x = x >>> 4;
}
Because there are no unsigned types in Java, on line int mask = 15 << 28; you practically make your mask negative by moving bits up to sign field. Later you move it left with mask = mask >> 4; and thus carry down the sign bit. After the shift, your mask is not 00001111000000000000000000000000 but 11111111000000000000000000000000. Use logical right shift operator >>> instead.
PS. This seems like a homework. In such cases, one who asks question should mark the question with homework tag.

(Java) Specify number of bits (length) when converting binary number to string?

I'm trying to store a number as a binary string in an array but I need to specify how many bits to store it as.
For example, if I need to store 0 with two bits I need a string "00". Or 1010 with 6 bits so "001010".
Can anyone help?
EDIT: Thanks guys, as I'm rubbish at maths/programming in general I've gone with the simplest solution which was David's. Something like:
binaryString.append(Integer.toBinaryString(binaryNumber));
for(int n=binaryString.length(); n<numberOfBits; n++) {
binaryString.insert(0, "0");
}
It seems to work fine, so unless it's very inefficient I'll go with it.
Use Integer.toBinaryString() then check the string length and prepend it with as many zeros as you need to make your desired length.
Forget about home-made solutions. Use standard BigInteger instead. You can specify number of bits and then use toString(int radix) method to recover what you need (I assume you need radix=2).
EDIT: I would leave bit control to BigInteger. The object will internally resize its bit buffer to fit the new number dimension. Moreover arithmetic operations can be carried out by means of this object (you do not have to implement binary adders/multipliers etc.). Here is a basic example:
package test;
import java.math.BigInteger;
public class TestBigInteger
{
public static void main(String[] args)
{
String value = "1010";
BigInteger bi = new BigInteger(value,2);
// Arithmetic operations
System.out.println("Output: " + bi.toString(2));
bi = bi.add(bi); // 10 + 10
System.out.println("Output: " + bi.toString(2));
bi = bi.multiply(bi); // 20 * 20
System.out.println("Output: " + bi.toString(2));
/*
* Padded to the next event number of bits
*/
System.out.println("Padded Output: " + pad(bi.toString(2), bi.bitLength() + bi.bitLength() % 2));
}
static String pad(String s, int numDigits)
{
StringBuffer sb = new StringBuffer(s);
int numZeros = numDigits - s.length();
while(numZeros-- > 0) {
sb.insert(0, "0");
}
return sb.toString();
}
}
This is a common homework problem. There's a cool loop that you can write that will compute the smallest power of 2 >= your target number n.
Since it's a power of 2, the base 2 logarithm is the number of bits. But the Java math library only offers natural logarithm.
math.log( n ) / math.log(2.0)
is the number of bits.
Even simpler:
String binAddr = Integer.toBinaryString(Integer.parseInt(hexAddr, 16));
String.format("%032", new BigInteger(binAddr));
The idea here is to parse the string back in as a decimal number temporarily (one that just so happens to consist of all 1's and 0's) and then use String.format().
Note that you basically have to use BigInteger, because binary strings quickly overflow Integer and Long resulting in NumberFormatExceptions if you try to use Integer.fromString() or Long.fromString().
Try this:
String binaryString = String.format("%"+Integer.toString(size)+"s",Integer.toBinaryString(19)).replace(" ","0");
where size can be any number the user wants
Here's a simple solution for int values; it should be obvious how to extend it to e.g. byte, etc.
public static String bitString(int i, int len) {
len = Math.min(32, Math.max(len, 1));
char[] cs = new char[len];
for (int j = len - 1, b = 1; 0 <= j; --j, b <<= 1) {
cs[j] = ((i & b) == 0) ? '0' : '1';
}
return new String(cs);
}
Here is the output from a set of sample test cases:
0 1 0 0
0 -1 0 0
0 40 00000000000000000000000000000000 00000000000000000000000000000000
13 1 1 1
13 2 01 01
13 3 101 101
13 4 1101 1101
13 5 01101 01101
-13 1 1 1
-13 2 11 11
-13 3 011 011
-13 4 0011 0011
-13 5 10011 10011
-13 -1 1 1
-13 40 11111111111111111111111111110011 11111111111111111111111111110011
Of course, you're on your own to make the length parameter adequate to represent the entire value.
import java.util.BitSet;
public class StringifyByte {
public static void main(String[] args) {
byte myByte = (byte) 0x00;
int length = 2;
System.out.println("myByte: 0x" + String.valueOf(myByte));
System.out.println("bitString: " + stringifyByte(myByte, length));
myByte = (byte) 0x0a;
length = 6;
System.out.println("myByte: 0x" + String.valueOf(myByte));
System.out.println("bitString: " + stringifyByte(myByte, length));
}
public static String stringifyByte(byte b, int len) {
StringBuffer bitStr = new StringBuffer(len);
BitSet bits = new BitSet(len);
for (int i = 0; i < len; i++)
{
bits.set (i, (b & 1) == 1);
if (bits.get(i)) bitStr.append("1"); else bitStr.append("0");
b >>= 1;
}
return reverseIt(bitStr.toString());
}
public static String reverseIt(String source) {
int i, len = source.length();
StringBuffer dest = new StringBuffer(len);
for (i = (len - 1); i >= 0; i--)
dest.append(source.charAt(i));
return dest.toString();
}
}
Output:
myByte: 0x0
bitString: 00
myByte: 0x10
bitString: 001010
So here instead of 8 you can write your desired length and it will append zeros accordingly. If the length of your mentioned integer exceeds that of the number mentioned then it will not append any zeros
String.format("%08d",1111);
Output:00001111
String.format("%02d",1111);
output:1111

Categories

Resources