Simulating Signed Bit Multiplication in Java - java

I'm attempting to create a java simulator that will simulate all the possible signed multiplications for 4 bit numbers.
My code layout uses chars to represent the actual bits.
My issue I have now is splitting up my int inputs (multiplicand/multiplier) bit by bit to place each bit into a new char so I can manipulate each char (ie bit) to perform signed multiplication.
Any pointers are greatly appreciated
public class SignedMultiplication {
int multiplicand, multiplier, expected_product, actual_product;
char md_bit0, md_bit1, md_bit2, md_bit3, mr_bit0, mr_bit1, mr_bit2, mr_bit3;
char pr_bit0, pr_bit1, pr_bit2, pr_bit3, pr_bit4, pr_bit5, pr_bit6, pr_bit7;
for(multiplicand=-8;multiplicand<8;++multiplicand){
// set multiplicand bits for two's complement
md_bit0 = ;
md_bit1 = ;
md_bit2 = ;
md_bit3 = ;
for(multiplier = -8; multiplier < 8; ++multiplier){
// set multiplier bits for two's complement
mr_bit0 = ;
mr_bit1 = ;
mr_bit2 = ;
mr_bit3 = ;
// perform 4 bit multiplier operation
// result is in pr_bit0 through pr_bit7
// set actual product to value converting 2's complement to an integer
actual_product = ;
expected_product = multiplicand * multiplier;
if( expected_product != actual_product ){
System.out.println("Multiplicand: " + multiplicand + " Multiplier: " + multiplier +
" Expected Result: " + expected_product + " Obtained: " + actual_product );
}
}
}
}

Related

How produce two's complement of a Uint16?

I have two bytes of data. I converted each of them to Uint8 then I produced a Uint16 from them.
How I can produce two's complement of this Uint16 number?
I've tried uInt16 = ~uInt16 + 1 but the code produces 32bit integer and I want it to stay a 16bit Integer.
byte firstByte, secondByte;
int firstUint8, secondUint8, uInt16;
firstByte = buffer[index];//get first byte from buffer
secondByte = buffer[index + 1];//get second byte from buffer
firstUint8=firstByte & 0xFF;//produce Uint8
secondUint8 = secondByte & 0xFF;//produce Uint8
uInt16 = 256 * firstUint8 + secondUint8;//create Uint16 from these to Uint8
twosComplementOfUInt16=~number+1; //produce 32 bit integer but I want int16
Java is not the best programing language to work with bits. But if you want you can read the documentation to see how the number are represented in java; how to work with bytes or you can do a tutorial.
As observation the (~ and +) returns an integer
public static void main(String[] args) {
int uint8 = 0xff;
int uint16 = 0xffff;
long uint32 = 0xffffffff;
int one = 0x0001;
int ten = 0x000A;
int twoComplementOfTen = 0xFFF6;
int computedTwoComplementOfTen = ~ten + one;
int revertTwoComplementOfTen = ~twoComplementOfTen + one;
System.out.printf("One = 0x%04X \n", one);
System.out.printf("ten = 0x%04X \n", ten);
System.out.printf("~ten + one = 0x%04X \n", twoComplementOfTen);
System.out.printf("Computed ~ten + one = 0x%04X \n", computedTwoComplementOfTen);
System.out.printf("~twoComplementOfTen + one = 0x%04X \n", revertTwoComplementOfTen);
System.out.printf("Computed ~ten + one with uint16 mask = 0x%04X \n", uint16 & computedTwoComplementOfTen);
System.out.printf("~twoComplementOfTen + one with uint16 mask = 0x%04X \n", uint16 & revertTwoComplementOfTen);
}
Output:
One = 0x0001
Ten = 0x000A
~ten + one = 0xFFF6
Computed ~ten + one = 0xFFFFFFF6
~twoComplementOfTen + one = 0xFFFF000A
Computed ~ten + one with uint16 mask = 0xFFF6
~twoComplementOfTen + one with uint16 mask = 0x000A
The "twos complement" of a number is obtained by negation, at least on machines that use twos-complement representation of integers, which is true for nearly all modern hardware and is true for the Java virtual machine.
short x;
...set value of x...
x = -x;
In twos-complement hardware and in the Java virtual machine, negation is equivalent to invert and add one. The following demonstrates this:
Example:
public class Foo {
public static void main(String[] args) {
short n = 2; n = -n;
System.out.println(n);
short m = 2; m = ~m + 1;
System.out.println(m);
}
}
The output from the above is identical for m and n.
If you find it necessary to use 32-bit ints for the value then you can simply mask the result to 16 bits.
int uint16 = some_value;
int compl = -uint16 & 0xffff;

convert array numbers to negative

Java. I want to make an array of binary numbers available in negative form but I want the original positive binary numbers to remain there as well so I can use both positive and negative numbers in my program, but I can't find out a way to convert all the binary numbers I have in my array to negative binary numbers.
class Logicgates {
public static void main (String args[]) {
String binary[] = {
"0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111"
};
int a = 3;
int b = 5;
int c = a | b; // 0010|0100 = 0110
int d = a & b; // 0010&0100 = 0000
int ff= a ^ b;
int f = ~((~a&b) ^ (~b | a));
int g = ~f | 0x0f;
System.out.println("a = " + binary[a]);
System.out.println("b = " + binary[b]);
System.out.println("c = " + binary[c]);
System.out.println("d = " + binary[d]);
System.out.println("ff = " + binary[ff]);
System.out.println("f = " + binary[f]);
System.out.println("g = " + binary[g]);
}
}
here the value of g is -1 but since my array only contains positive 1 I can't print it.
If you want to use your original array I completely understand, as it may be a requirement to your assignment / project / learning experience.
If not, Java actually has a built in function in the java.lang library that will convert a decimal number to a binary number. The output may not be exactly what you are looking for, so you may have to make a few changes.
import java.lang.*;
public static void main(String[] args) {
int positive = 14;
System.out.println("Positive Number = " + positive);
int negative = -14;
System.out.println("Negative Number = " + negative);
//to binary
System.out.println("Positive Binary is " + Integer.toBinaryString(positive));
System.out.println("Negative Binary is " + Integer.toBinaryString(negative));
}
The output for this snippet will be
Positive Number = 14
Negative Number = -14
Positive Binary is 1110
Negative Binary is 11111111111111111111111111110010
As you can see, the negative number outputs the entire 32-bit string, but it should be simple enough for you to trim it down to the size you are looking for (e.g. 4-bit or 5-bit).
With this approach you won't be required to have your array of binary strings. You can simply pass the number to the toBinaryString() function and it will convert it for you.
After that you just need to add your logic for the gates you are trying to simulate.
Hopefully this points you in the right direction. Good luck!

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;
}

Total value of sum of integers does not equal calculated value

While doing unsigned int conversions in Java I got some "anomalous" results, which I have cut down to the minimal case shown below. The same code in C generates similar results.
The problem is that when I calculate the theoretical sum of the absolute value of all integer values using the Gauss summation formula n(n+1)/2 (see https://en.wikipedia.org/wiki/Summation) the value I calculate does not match the total if I actually add up all the absolute values one by one.
Note that when I calculate the total using the summation formula the division by 2 "/2" is omitted because I am adding both the negative and positive numbers as absolute values, and at the end I have to add (longIntegerMax + 1) because the negative numbers have one extra number at the end (Integer.MIN) which has the absolute value of Integer.MAX + 1.
public static void main( String[] asArguments ){
long longAbsoluteTotal = 0;
long longNumberOfIntegers = 0;
long longIntegerMax = Integer.MAX_VALUE;
long longIntegerMin = Integer.MIN_VALUE;
for( int i = Integer.MIN_VALUE;; i++ ){
longNumberOfIntegers++;
if( i < 0 ){
longAbsoluteTotal += i * -1;
} else {
longAbsoluteTotal += i;
}
if( i == Integer.MAX_VALUE ) break;
}
long longCalculatedTotal = longIntegerMax * (longIntegerMax + 1) + longIntegerMax + 1;
System.out.println( "count of all integers: " + longNumberOfIntegers );
System.out.println( "total of absolute value of all integers: " + longAbsoluteTotal );
System.out.println( "calculated total of absolute value of all integers: " + longCalculatedTotal );
}
output:
count of all integers: 4294967296
total of absolute value of all integers: 4611686014132420608
calculated total of absolute value of all integers: 4611686018427387904
As you can see, the calculated total is close to the real total, but does not match it exactly. Why not?
The problem is here ..
longAbsoluteTotal += i * -1;
The ( i * -1 ) is still integer arithmetic, it produces a number greater than Integer.MAX_VALUE and overflows back to Integer.MIN_VALUE;
You could fix this as #Evgeniy suggested, or you could use
longAbsoluteTotal += i * -1L;
to force long arithmetic.
4611686014132420608 - 4611686018427387904 = -4294967296 = Integer.MIN_VALUE * 2
The reason is that
Integer.MIN_VALUE * -1 == Integer.MIN_VALUE
Since we use two's complement to represent negative value.
The two's complement of Integer.MIN_VALUE(0x80000000) = 0x7fffffff + 0x1 = 0x80000000.
Change
for( int i = Integer.MIN_VALUE;; i++ ){
to
for( long i = Integer.MIN_VALUE;; i++ ){
all will be OK
It's similar to -Integer.MIN_VALUE == -2147483648

How Can I Convert Very Large Decimal Numbers to Binary In Java

For instance, How would I be able to convert 2^60 or 12345678901234567890123456789012345678901234567890 to binary?
Basically, numbers that are too large to represent in Java.
Edit: I will be making a class that will be able to represent number that are too large. I'm just having a hard time figuring our how to convert decimal to binary.
Edit2: And also, I am not allowed to use BigDecimal, BigInteger, or any other library, sorry for not specifying earlier.
Here is a quik&dirty (very very very dirty) code:
public class BigDec2Bin {
public static int[] string2arrayReversed( String s )
{
char a[] = s.toCharArray();
int b[] = new int[ s.length() ];
for( int i = 0; i < a.length; i++ )
{
b[a.length-1-i] = a[i] - 48;
}
return b;
}
// adds two binary numbers represented as strings
public static String add( String s1, String s2 )
{
String result = "", stmp;
int[] a1, a2;
int ctmp, mark = 0;
// a1 should be the longer one
a1 = string2arrayReversed( ( s1.length() > s2.length() ? s1 : s2 ) );
a2 = string2arrayReversed( ( s1.length() < s2.length() ? s1 : s2 ) );
for( int i = 0; i < a1.length; i++ )
{
ctmp = a1[i] + ( i < a2.length ? a2[i] : 0 ) + mark;
switch( ctmp )
{
default:
case 0:
stmp = "0";
mark = 0;
break;
case 1:
stmp = "1";
mark = 0;
break;
case 2:
stmp = "0";
mark = 1;
break;
case 3:
stmp = "1";
mark = 1;
break;
}
result = stmp + result;
}
if( mark > 0 ) { result = "1" + result; }
return result;
}
public static String dec2bin( String s )
{
String result = "";
for( int i = 0; i < s.length() ; i++ )
{
result = add( result + "0", result + "000" );
result = add( result, Integer.toBinaryString( s.charAt(i) - 48 ) );
}
return result;
}
public static void main( String[] args )
{
String dec = "12345"; // should be 11000000111001
System.out.println( "dec2bin( " + dec + " ) = " + dec2bin( dec ) );
dec = "12345678901234567890123456789012345678901234567890";
System.out.println( "dec2bin( " + dec + " ) = " + dec2bin( dec ) );
}
}
Output:
dec2bin( 12345 ) = 011000000111001
dec2bin(
12345678901234567890123456789012345678901234567890
) =
10000111001001111111011000110110100110101010111110000011110010100001010100000010011001110100011110101111100011000111111100011001011011001110001111110000101011010010
My main idea is to use always strings.
add -method adds two binary numbers which are represented as strings
dec2bin -method is where the magic happens.
Allow me to explain:
result = add( result + "0", result + "000" );
is a calculation to multiply any given number by 10.
Multiplying a binary number by 10 is the same as adding the number with shifts:
x*10 <=> x<<1 + x<<3
result = add( result, Integer.toBinaryString( s.charAt(i) - 48 ) );
just adds a the next digit (from left to right) on the result string
Basicly what I'm doing is for example with 1234:
0*10 + 1 = 1
1*10 + 2 = 12
12*10 + 3 = 123
123*10 + 4 = 1234
but only in binary (represented as strings).
I hope i could help and sorry for my bad english.
Try this:
new BigDecimal("12345678901234567890123456789012345678901234567890").toString(2);
Edit:
For making a big-number class, you may want to have a look at my post about this a week ago. Ah, the question was by you, never mind.
The conversion between different number systems in principle is a repeated "division, remainder, multiply, add" operation. Let's look at an example:
We want to convert 123 from decimal to a base 3 number. What do we do?
Take the remainder modulo 3 - prepend this digit to the result.
Divide by 3.
If the number is bigger than 0, continue with this number at step 1
So it looks like this:
123 % 3 == 0. ==> The last digit is 0.
123 / 3 == 41.
41 % 3 == 2 ==> The second last digit is 2.
41 / 3 == 13
13 % 3 == 1 ==> The third digit is 1.
13 / 3 == 4
4 % 3 == 1 ==> The fourth digit is 1 again.
4 / 3 == 1
1 % 3 == 1 ==> The fifth digit is 1.
So, we have 11120 as the result.
The problem is that for this you need to have already some kind of division by 3 in decimal format, which is usually not the case if you don't implement your number in a decimal-based format (like I did in the answer to your last question linked above).
But it works for converting from your internal number format to any external format.
So, let's look at how we would do the inverse calculation, from 11120 (base 3) to its decimal equivalent. (Base 3 is here the placeholder for an arbitrary radix, Base 10 the placeholder for your internal radix.) In principle, this number can be written as this:
1 * 3^4 + 1 * 3^3 + 1*3^2 + 2*3^1 + 0*3^0
A better way (faster to calculate) is this:
((((1 * 3) + 1 )*3 + 1 )*3 + 2)*3 + 0
1
3
4
12
13
39
41
123
123
(This is known as Horner scheme, normally used for calculating values of polynomials.)
You can implement this in the number scheme you are implementing, if you know how to represent the input radix (and the digits) in your target system.
(I just added such a calculation to my DecimalBigInt class, but you may want to do the calculations directly in your internal data structure instead of creating a new object (or even two) of your BigNumber class for every decimal digit to be input.)
What about this approach:
result = 0;
for each digit in the decimal number, from left to right
result = result * 10 + digit;
return result;
So we need a way to represent an arbitrarily large binary number, and implement multiplication by 10 and addition of small numbers.
The most straightforward way to represent an arbitrarily large binary number is an array of its binary digits. You can then apply the algorithms for addition and multiplication your learned in elementary school, except that digits will "overflow" when they exceed 1 rather than 9. For example:
1010 * 1100111
----------------
11001110
+ 1100111000
----------------
10000000110
Pew: thanks, that works for some numbers. The number 6123456789012 however doesn't work, but here is the fix:
// a1 should be the longer one
a1 = string2arrayReversed( ( s1.length() >= s2.length() ? s1 : s2 ) ); //GREATER EQUAL
If you only work with integers, use BigInteger.toByteArray.
If not, unfortunately BigDecimal doesn't have that method. But I suppose you can always (in both cases) just ASCII encode the string representation of the number, if the binary form is just meant for transfer and not calculation anywhere.
there is a fast program to get the binary representation of a huge decimal.
This programm is indeed fast, it takes only 20ms to deal with a decimal with 3000digits, eg:string(3000,'2')+'12345'. because of the pursuit of efficiency, it is not very readable. you can modify it yourself to make it easier to understand.
inline string remove_pre_zero(const string& a)
{
auto t = a.find_first_not_of('\0', 0);
if (t == a.npos)
return string("0");
else
return a.substr(t);
}
string convert_to_bin(const string& _s)
{
const static string str[] = { "0", "1" };
string s(_s.size(), '0');
string binary;
binary.reserve(_s.size()*3);
int i = 0;
for (const auto& c : _s)
s[i++] = (c - '0');
while (s!="0")//simulate divide by 2
{
int t = 0, old_t = 0;
for (auto& ch : s)
{
t = ((old_t * 10 + ch) & 1);
ch = (ch + old_t * 10) >>1;
old_t = t;
}
binary += str[t];
if (s[0] == 0)
s = remove_pre_zero(s);
}
return string(binary.rbegin(), binary.rend());
}

Categories

Resources