How to do arithmetic operations in binary with Java? - java

For a Java assignment I am required to be able to pass any number that will be introduced as a string through the command line (no matter how big) into binary.
Then generate methods that will allow these numbers to add, multiply, subtract and divide.
My question would be first:
How do I make my string into binary
Eg:
123 would become 1111011
8403678 would become 100000000011101011011110
And so forth...
Then the biggest issue is to get them to add up, subtract each other, etc.
Last I need to be able to convert back the result from binary back to decimal which I am having more trouble understanding how to do it than the previous case (transforming from binary into a decimal string).
Eg:
if 1111011 was added to 100000000011101011011110 the result would be 100000000011101101011001 and then it would become 8403801 which I would print out as a result.
The final aim of this project is to create our own class such as java.math.BigInteger (without using it of course) and handling arbitrarily big numbers (bigger than what Int can handle).
If there is any extra information required please let me know I will answer promptly.

Since you have to be able to handle large numbers without using BigInteger, you need to find a way to represent arbitrarily large numbers. Obviously int will not do. One easy way is to represent the number as a String. For instance, the number 123 could be stored as the String "123".
Converting to binary will require some intermediate operations such as division and modulo. Thus, it is worth thinking about how to do these when your numbers are stored in Strings. Since this is homework I don't want to just give you the answer, but some guidance instead.
Say you want to do addition.
Think about how you add big numbers by hand. Which digits of each number do you use, and how do you manipulate them to get the answer? This algorithm is fairly straightforward, and once you can explain it, you can give a computer directions to do it as well. (For addition, you add first the one's digits, then the ten's digits, etc... and remember to carry if you have to!)
Note that you can get the digits of your number String by using a method such as charAt(int n). This will return the character at index n of the string. Convert it to an Integer by using Integer.parseInt() (which takes a numeric string and converts it to an integer).
So now you can think: If I want the one's digit of a number, what index would that be in a String? Starting with this, you should be able to figure out how to get any digit you want from a big number string. Now, you can implement your algorithm.
Finally, to convert from base ten to binary you do need to understand how number bases work. This gives a clear and quick introduction: http://www.math.grin.edu/~rebelsky/Courses/152/97F/Readings/student-binary
The section "Converting from decimal to binary" in the above link describes a method for exactly what you want to do. Good luck.

Related

Can someone explain the Math.ulp(double) method?

I haven't been able to find any information online that doesn't already assume I know things. I wonder if anyone knows any good resources that I can look into to help me wrap my head around what this function does exactly?
From what I gather, and I'm pretty certain this is wrong or at least not fully right, is that given a floating point, it determines the distance between itself and some number next in a sequence? There appears to be something to do with how number are represented bitwise, but the sources I've read never explicitly said anything about that.
http://matlabgeeks.com/tips-tutorials/floating-point-comparisons-in-matlab/
illustrated it rather well:
float2bin(A)
//ans = 0011111110111001100110011001100110011001100110011001100110100000
float2bin(B)
//ans = 0011111110111001100110011001100110011001100110011001100110011010
You can see the difference in precision at a binary level in this example. A and B differ by 6 ulps (units in the last place)
I believe that it is showing the distance between the number you specify, and the next largest binary float that can be encoded.
Because of the range that binary floating point numbers cover and their precision, not all numbers between any two given real numbers are covered, so it looks like this is giving you the positive distance between the number you wish to encode and the actual number it would be stored as.
From Wikipedia:
the unit of least precision (ULP) is the spacing between floating-point numbers, i.e., the value the least significant digit represents if it is 1

Large Inputs in JAVA

I have to solve a problem in java which has an input consisting of 10^100 digits.
How can I take such a large input and process it.I am using JAVA as my programming language.
Are all those digits actually significant? Or do you just have a value like 1.234567890123456789 * 10^100?
As others have noted, having 10^100 essential digits would essentially mean you can stop now and write off your problem as uncomputable. You've either misunderstood it, or you shouldn't be approching it via brute-force number crunching. Or both.
If you don't need all the lower-order digits, then floats or doubles may do the job for you. If you need more digits of precision than a double can handle (but still a REASONABLE number), an extended-precision floating point package such as BigFloat might get you there.
If you told us what you were actually trying to do, we could tell you more about whether there's any reasonable way to do it.

Convert string to a large integer?

I have an assignment (i think a pretty common one) where the goal is to develop a LargeInteger class that can do calculations with.. very large integers.
I am obviously not allowed to use the Java.math.bigeinteger class at all.
Right off the top I am stuck. I need to take 2 Strings from the user (the long digits) and then I will be using these strings to perform the various calculation methods (add, divide, multiply etc.)
Can anyone explain to me the theory behind how this is supposed to work? After I take the string from the user (since it is too large to store in int) am I supposed to break it up maybe into 10 digit blocks of long numbers (I think 10 is the max long maybe 9?)
any help is appreciated.
First off, think about what a convenient data structure to store the number would be. Think about how you would store an N digit number into an int[] array.
Now let's take addition for example. How would you go about adding two N digit numbers?
Using our grade-school addition, first we look at the least significant digit (in standard notation, this would be the right-most digit) of both numbers. Then add them up.
So if the right-most digits were 7 and 8, we would obtain 15. Take the right-most digit of this result (5) and that's the least significant digit of the answer. The 1 is carried over to the next calculation. So now we look at the 2nd least significant digit and add those together along with the carry (if there is no carry, it is 0). And repeat until there are no digits left to add.
The basic idea is to translate how you add, multiply, etc by hand into code when the numbers are stored in some data structure.
I'll give you a few pointers as to what I might do with a similar task, but let you figure out the details.
Look at how addition is done from simple electronic adder circuits. Specifically, they use small blocks of addition combined together. These principals will help. Specifically, you can add the blocks, just remember to carry over from one block to the next.
Your idea of breaking it up into smaller blogs is an excellent one. Just remember to to the correct conversions. I suspect 9 digits is just about right, for the purpose of carry overs, etc.
These tasks will help you with addition and subtraction. Multiplication and Division are a bit trickier, but again, a few tips.
Multiplication is the easier of the tasks, just remember to multiply each block of one number with the other, and carry the zeros.
Integer division could basically be approached like long division, only using whole blocks at a time.
I've never actually build such a class, so hopefully there will be something in here you can use.
Look at the source code for MPI 1.8.6 by Michael Bromberger (a C library). It uses a simple data structure for bignums and simple algorithms. It's C, not Java, but straightforward.
Its division performs poorly (and results in slow conversion of very large bignums to tex), but you can follow the code.
There is a function mpi_read_radix to read a number in an arbitrary radix (up to base 36, where the letter Z is 35) with an optional leading +/- sign, and produce a bignum.
I recently chose that code for a programming language interpreter because although it is not the fastest performer out there, nor the most complete, it is very hackable. I've been able to rewrite the square root myself to a faster version, fix some coding bugs affecting a port to 64 bit digits, and add some missing operations that I needed. Plus the licensing is BSD compatible.

Handling large numbers

I have this problem:
A positive integer is called a palindrome if its representation in the decimal system is the same when read from left to right and from right to left. For a given positive integer K of not more than 1000000 digits, write the value of the smallest palindrome larger than K to output. Numbers are always displayed without leading zeros.
Input
The first line contains integer t, the number of test cases. Integers K are given in the next t lines.
Output
For each K, output the smallest palindrome larger than K.
Example
Input:
2
808
2133
Output:
818
2222
My code converts the input to a string and evaluates either end of the string making adjustments accordingly and moves inwards. However, the problem requires that it can take values up to 10^6 digits long, if I try to parse large numbers I get a number format exception i.e.
Integer.parseInt(LARGENUMBER);
or
Long.parseInt(LARGENUMBER);
and LARGENUMBER is out of range. can anyone think of a work around or how to handle such large numbers?
You could probably use the BigInteger class to handle large integers like this.
However, I wouldn't count on it being efficient at such massive sizes. Because it still uses O(n^2) algorithms for multiplication and conversions.
Think of your steps that you do now. Do you see something that seems a little superfluous since you're converting the number to a string to process it?
While this problem talks about integers, its doing so only to restrict the input and output characters and format. This is really a string operations question with careful selection. Since this is the case, you really don't need to actually read the input in as integers, only strings.
This will make validating the palindrome simple. The only thing you should need to work out is choosing the next higher one.

how can i generate a unique int from a unique string?

I have an object with a String that holds a unique id .
(such as "ocx7gf" or "67hfs8")
I need to supply it an implementation of int hascode() which will be unique obviously.
how do i cast a string to a unique int in the easiest/fastest way?
10x.
Edit - OK. I already know that String.hashcode is possible. But it is not recommended in any place. Actually' if any other method is not recommended - Should I use it or not if I have my object in a collection and I need the hashcode. should I concat it to another string to make it more successful?
No, you don't need to have an implementation that returns a unique value, "obviously", as obviously the majority of implementations would be broken.
What you want to do, is to have a good spread across bits, especially for common values (if any values are more common than others). Barring special knowledge of your format, then just using the hashcode of the string itself would be best.
With special knowledge of the limits of your id format, it may be possible to customise and result in better performance, though false assumptions are more likely to make things worse than better.
Edit: On good spread of bits.
As stated here and in other answers, being completely unique is impossible and hash collisions are possible. Hash-using methods know this and can deal with it, but it does impact upon performance, so we want collisions to be rare.
Further, hashes are generally re-hashed so our 32-bit number may end up being reduced to e.g. one in the range 0 to 22, and we want as good a distribution within that as possible to.
We also want to balance this with not taking so long to compute our hash, that it becomes a bottleneck in itself. An imperfect balancing act.
A classic example of a bad hash method is one for a co-ordinate pair of X, Y ints that does:
return X ^ Y;
While this does a perfectly good job of returning 2^32 possible values out of the 4^32 possible inputs, in real world use it's quite common to have sets of coordinates where X and Y are equal ({0, 0}, {1, 1}, {2, 2} and so on) which all hash to zero, or matching pairs ({2,3} and {3, 2}) which will hash to the same number. We are likely better served by:
return ((X << 16) | (x >> 16)) ^ Y;
Now, there are just as many possible values for which this is dreadful than for the former, but it tends to serve better in real-world cases.
Of course, there is a different job if you are writing a general-purpose class (no idea what possible inputs there are) or have a better idea of the purpose at hand. For example, if I was using Date objects but knew that they would all be dates only (time part always midnight) and only within a few years of each other, then I might prefer a custom hash code that used only the day, month and lower-digits of the years, over the standard one. The writer of Date though can't work on such knowledge and has to try to cater for everyone.
Hence, If I for instance knew that a given string is always going to consist of 6 case-insensitive characters in the range [a-z] or [0-9] (which yours seem to, but it isn't clear from your question that it does) then I might use an algorithm that assigned a value from 0 to 35 (the 36 possible values for each character) to each character, and then walk through the string, each time multiplying the current value by 36 and adding the value of the next char.
Assuming a good spread in the ids, this would be the way to go, especially if I made the order such that the lower-significant digits in my hash matched the most frequently changing char in the id (if such a call could be made), hence surviving re-hashing to a smaller range well.
However, lacking such knowledge of the format for sure, I can't make that call with certainty, and I could well be making things worse (slower algorithm for little or even negative gain in hash quality).
One advantage you have is that since it's an ID in itself, then presumably no other non-equal object has the same ID, and hence no other properties need be examined. This doesn't always hold.
You can't get a unique integer from a String of unlimited length. There are 4 billionish (2^32) unique integers, but an almost infinite number of unique strings.
String.hashCode() will not give you unique integers, but it will do its best to give you differing results based on the input string.
EDIT
Your edited question says that String.hashCode() is not recommended. This is not true, it is recommended, unless you have some special reason not to use it. If you do have a special reason, please provide details.
Looks like you've got a base-36 number there (a-z + 0-9). Why not convert it to an int using Integer.parseInt(s, 36)? Obviously, if there are too many unique IDs, it won't fit into an int, but in that case you're out of luck with unique integers and will need to get by using String.hashCode(), which does its best to be close to unique.
Unless your strings are limited in some way or your integers hold more bits than the strings you're trying to convert, you cannot guarantee the uniqueness.
Let's say you have a 32 bit integer and a 64-character character set for your strings. That means six bits per character. That will allow you to store five characters into an integer. More than that and it won't fit.
represent each string character by a five-digit binary digit, eg. a by 00001 b by 00010 etc. thus 32 combinations are possible, for example, cat might be written as 00100 00001 01100, then convert this binary into decimal, eg. this would be 4140, thus cat would be 4140, similarly, you can get cat back from 4140 by converting it to binary first and Map the five digit binary to string
One way to do it is assign each letter a value, and each place of the string it's own multiple ie a = 1, b = 2, and so on, then everything in the first digit (read left to right) would be multiplied by a prime number, the next the next prime number and so on, such that the final digit was multiplied by a prime larger than the number of possible subsets in that digit (26+1 for a space or 52+1 with capitols and so on for other supported characters). If the number is mapped back to the first digits (leftmost character) any number you generate from a unique string mapping back to 1 or 6 whatever the first letter will be, gives a unique value.
Dog might be 30,3(15),101(7) or 782, while God 33,3(15),101(4) or 482. More importantly than unique strings being generated they can be useful in generation if the original digit is kept, like 30(782) would be unique to some 12(782) for the purposes of differentiating like strings if you ever managed to go over the unique possibilities. Dog would always be Dog, but it would never be Cat or Mouse.

Categories

Resources