I'm currently trying to solve the binary gap problem in java and started off with first trying to convert the decimal into binary using a while loop. I was testing it with different decimal inputs, but noticed after stepping through it, that on the final loop I'm getting integer overflow instead of appending a 1, (or at least I think I am, it goes from 100010000 to 411065418, I'm assuming because it multiples the 100010000 *10)
I tried stepping through it and This is my code currently:
public class BinaryGap {
public static void main(String[] args) {
// write your code in Java SE 8
int decimal = 529;
int ans =0;
//returns the number in binary but in big endian form
while(decimal != 0){
ans += (decimal % 2);
ans *= 10;
decimal /=2;
}
}
}
Any help in telling me where my line of thinking is wrong would be greatly appreciated
Your code is conceptually working fine - but variable 'ans' meets the limit of int - 2147483647. When +1 is added to this value - variable overflows and goes to minimal value.
To overcome it you can use type 'String' for 'ans' variable with small adjustments to code:
int decimal = 529;
String ans = "";
//returns the number in binary but in big endian form
while(decimal != 0){
ans += (decimal % 2);
decimal /=2;
}
Related
This question already has answers here:
Get a specific digit of a number from an int in Java [duplicate]
(4 answers)
Closed 3 years ago.
How to extract the hundred of an int variable?
For example, I have a random number:
int i = 5654217;
I want code to extract the number "2".
I tried to do
i/100
Which gave me 56542.
But I can't find a way to extract only the last number.
Too, I'm really unsure this is the best way to extract the hundred of the variable.
I am not 100% sure what you are asking so I will put the two guesses that I have of what your question is. If it doesn't answer your question please feel free to let me know, I will help you.
1) You are dividing an integer (int) by 100 and the last 2 digits disappear.
double x = (double)i/100.0;
//ints cannot store a decimal
2) You have a decimal (double) and are trying to output hundreds digit.
public int hundredthsDigit(double x){
if(x>0.0) return (x/100)%10;
//This moves the 100s digit to the 1s digit and removes the other digits by taking mod 10
return 10-Math.abs(x/100)%10;
// does practically the same thing, but is a work around as mod doesn't work with negatives in java
}
The modulus operator, % effectively gives you the remainder of a division.
You can get the last digit by getting the number, mod 10. Try (i / 100) % 10
You can read up more on modular arithmetic and such here: https://en.m.wikipedia.org/wiki/Modular_arithmetic
Please find code below:
package com.shree.test;
public class FindNumber {
public static int findNumberAt(int location,int inputNumber) {
int number = 0;
//number = (inputNumber % (location*10))/location; // This also works
number = (inputNumber/location)%10; // But as mentioned in other comments and answers, this line is perfect solution
return number;
}
public static void main(String[] args) {
System.out.println(findNumberAt(100, 5654217));
}
}
I have a decimal number which I need to convert to binary and then find the position of one's in that binary representation.
Input is 5 whose binary is 101 and Output should be
1
3
Below is my code which only provides output as 2 instead I want to provide the position of one's in binary representation. How can I also get position of set bits starting from 1?
public static void main(String args[]) throws Exception {
System.out.println(countBits(5));
}
private static int countBits(int number) {
boolean flag = false;
if (number < 0) {
flag = true;
number = ~number;
}
int result = 0;
while (number != 0) {
result += number & 1;
number = number >> 1;
}
return flag ? (32 - result) : result;
}
Your idea of having countBits return the result, instead of putting a System.out.println inside the method, is generally the best approach. If you want it to return a list of bit positions, the analogue would be to have your method return an array or some kind of List, like:
private static List<Integer> bitPositions(int number) {
As I mentioned in my comments, you will make life a lot easier for yourself if you use >>> and get rid of the special code to check for negatives. Doing this, and adapting the code you already have, gives you something like
private static List<Integer> bitPositions(int number) {
List<Integer> positions = new ArrayList<>();
int position = 1;
while (number != 0) {
if (number & 1 != 0) {
positions.add(position);
}
position++;
number = number >>> 1;
}
return positions;
}
Now the caller can do what it wants to print the positions out. If you use System.out.println on it, the output will be [1, 3]. If you want each output on a separate line:
for (Integer position : bitPositions(5)) {
System.out.println(position);
}
In any case, the decision about how to print the positions (or whatever else you want to do with them) is kept separate from the logic that computes the positions, because the method returns the whole list and doesn't have its own println.
(By the way, as Alex said, it's most common to think of the lower-order bit as "bit 0" instead of "bit 1", although I've seen hardware manuals that call the low-order bit "bit 31" and the high-order bit "bit 0". The advantage of calling it "bit 0" is that a 1 bit in position N represents the value 2N, making things simple. My code example calls it "bit 1" as you requested in your question; but if you want to change it to 0, just change the initial value of position.)
Binary representation: Your number, like anything on a modern day (non-quantum) computer, is already a binary representation in memory, as a sequence of bits of a given size.
Bit operations
You can use bit shifting, bit masking, 'AND', 'OR', 'NOT' and 'XOR' bitwise operations to manipulate them and get information about them on the level of individual bits.
Your example
For your example number of 5 (101) you mentioned that your expected output would be 1, 3. This is a bit odd, because generally speaking one would start counting at 0, e.g. for 5 as a byte (8 bit number):
76543210 <-- bit index
5 00000101
So I would expect the output to be 0 and 2 because the bits at those bit indexes are set (1).
Your sample implementation shows the code for the function
private static int countBits(int number)
Its name and signature imply the following behavior for any implementation:
It takes an integer value number and returns a single output value.
It is intended to count how many bits are set in the input number.
I.e. it does not match at all with what you described as your intended functionality.
A solution
You can solve your problem using a combination of a 'bit shift' (>>) and an AND (&) operation.
int index = 0; // start at bit index 0
while (inputNumber != 0) { // If the number is 0, no bits are set
// check if the bit at the current index 0 is set
if ((inputNumber & 1) == 1)
System.out.println(index); // it is, print its bit index.
// advance to the next bit position to check
inputNumber = inputNumber >> 1; // shift all bits one position to the right
index = index + 1; // so we are now looking at the next index.
}
If we were to run this for your example input number '5', we would see the following:
iteration input 76543210 index result
1 5 00000101 0 1 => bit set.
2 2 00000010 1 0 => bit not set.
3 1 00000001 2 1 => bit set.
4 0 00000000 3 Stop, because inputNumber is 0
You'll need to keep track of what position you're on, and when number & 1 results in 1, print out that position. It look something like:
...
int position = 1;
while (number != 0) {
if((number & 1)==1)
System.out.println(position);
result += number & 1;
position += 1;
number = number >> 1;
}
...
There is a way around working with bit-wise operations to solve your problem.
Integer.toBinaryString(int number) converts an integer to a String composed of zeros and ones. This is handy in your case because you could instead have:
public static void main(String args[]) throws Exception {
countBits(5);
}
public static void countBits(int x) {
String binaryStr = Integer.toBinaryString(x);
int length = binaryStr.length();
for(int i=0; i<length; i++) {
if(binaryStr.charAt(i)=='1')
System.out.println(length-1);
}
}
It bypasses what you might be trying to do (learn bitwise operations in Java), but makes the code look cleaner in my opinion.
The combination of Integer.lowestOneBit and Integer.numberOfTrailingZeros instantly gives the position of the lowest 1-Bit, and returns 32 iff the number is 0.
Therefore, the following code returns the positions of 1-Bits of the number number in ascending order:
public static List<Integer> BitOccurencesAscending(int number)
{
LinkedList<Integer> out = new LinkedList<>();
int x = number;
while(number>0)
{
x = Integer.lowestOneBit(number);
number -= x;
x = Integer.numberOfTrailingZeros(x);
out.add(x);
}
return out;
}
I am trying to write a program which converts binary numbers into decimal, however as soon as I have a binary number which is bigger than 10 digits I get a java.lang.numberformatexception error. I was wondering how I should rewrite my code in order to handle binary numbers:
try{
//will throw an exception if the user's input contains a non-Integer
int inputNumber = Integer.parseInt(returnEnterNumber());
//when our user wants to convert from binary to decimal
if(binaryToDecimal.isSelected()){
//checks if number is binary
int checkNumber = inputNumber;
while (checkNumber != 0) {
if (checkNumber % 10 > 1) {
throw new InvalidBinaryException();
}
checkNumber = checkNumber / 10;
}
//converts from binary and outputs result
int n = Integer.parseInt(returnEnterNumber(), 2);
displayConvertedNumber(Integer.toString(n));
}
}
catch(Exception e) {
displayConvertedNumber("WRONG INPUT! - TRY again");
}
Edit: I understand why the code fails, seeing as how it takes the number as a decimal and overflows. I am not sure how to rewrite the code to take the input as a binary straight away.
That's not a valid way to check a binary number. You're converting to an int in base 10, then checking that each of the digits in base 10 is zero or one. The conversion itself will fail on long enough input strings, and if it doesn't the checking will fail as well.
You shouldn't be converting it all all, you should be checking the input string itself.
EDIT Actually you don't have to do anything. Integer.parseInt() will check it for you and throw NumberFormatException if the string isn't a number in the specified radix.
You are parsing your binary digit string as a decimal integer first. If it has more than 10 significant digits then its decimal interpretation is too big to fit in an int, so the decimal conversion fails.
When you are going to parse the digit string as a binary number, simply avoid first parsing it as a decimal one. For instance, most of what you posted could be reduced to this:
int inputNumber = Integer.parseInt(returnEnterNumber(),
binaryToDecimal.isSelected() ? 2 : 10);
Take a look at Integers MAX values:
public class MainClass {
public static void main(String[] arg) {
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
}
}
the output will be:
2147483647
-2147483648
This means that if you have more than 10 digits, you have exceeded the max number for the Integer data type.
Try Using BigInteger on your binary value or consider returning it as String
Here is one line of code that will accomplish what you are looking for
System.out.println(new BigInteger("10101010101010111101010101001101010101010101001010101010101001011101010101010101",2).toString());
This question already has answers here:
How to test if a double is an integer
(18 answers)
Closed 9 years ago.
Specifically in Java, how can I determine if a double is an integer? To clarify, I want to know how I can determine that the double does not in fact contain any fractions or decimals.
I am concerned essentially with the nature of floating-point numbers. The methods I thought of (and the ones I found via Google) follow basically this format:
double d = 1.0;
if((int)d == d) {
//do stuff
}
else {
// ...
}
I'm certainly no expert on floating-point numbers and how they behave, but I am under the impression that because the double stores only an approximation of the number, the if() conditional will only enter some of the time (perhaps even a majority of the time). But I am looking for a method which is guaranteed to work 100% of the time, regardless of how the double value is stored in the system.
Is this possible? If so, how and why?
double can store an exact representation of certain values, such as small integers and (negative or positive) powers of two.
If it does indeed store an exact integer, then ((int)d == d) works fine. And indeed, for any 32-bit integer i, (int)((double)i) == i since a double can exactly represent it.
Note that for very large numbers (greater than about 2**52 in magnitude), a double will always appear to be an integer, as it will no longer be able to store any fractional part. This has implications if you are trying to cast to a Java long, for instance.
How about
if(d % 1 == 0)
This works because all integers are 0 modulo 1.
Edit To all those who object to this on the grounds of it being slow, I profiled it, and found it to be about 3.5 times slower than casting. Unless this is in a tight loop, I'd say this is a preferable way of working it out, because it's extremely clear what you're testing, and doesn't require any though about the semantics of integer casting.
I profiled it by running time on javac of
class modulo {
public static void main(String[] args) {
long successes = 0;
for(double i = 0.0; i < Integer.MAX_VALUE; i+= 0.125) {
if(i % 1 == 0)
successes++;
}
System.out.println(successes);
}
}
VS
class cast {
public static void main(String[] args) {
long successes = 0;
for(double i = 0.0; i < Integer.MAX_VALUE; i+= 0.125) {
if((int)i == i)
successes++;
}
System.out.println(successes);
}
}
Both printed 2147483647 at the end.
Modulo took 189.99s on my machine - Cast took 54.75s.
if(new BigDecimal(d).scale() <= 0) {
//do stuff
}
Your method of using if((int)d == d) should always work for any 32-bit integer. To make it work up to 64 bits, you can use if((long)d == d, which is effectively the same except that it accounts for larger magnitude numbers. If d is greater than the maximum long value (or less than the minimum), then it is guaranteed to be an exact integer. A function that tests whether d is an integer can then be constructed as follows:
boolean isInteger(double d){
if(d > Long.MAX_VALUE || d < Long.MIN_VALUE){
return true;
} else if((long)d == d){
return true;
} else {
return false;
}
}
If a floating point number is an integer, then it is an exact representation of that integer.
Doubles are a binary fraction with a binary exponent. You cannot be certain that an integer can be exactly represented as a double, especially not if it has been calculated from other values.
Hence the normal way to approach this is to say that it needs to be "sufficiently close" to an integer value, where sufficiently close typically mean "within X %" (where X is rather small).
I.e. if X is 1 then 1.98 and 2.02 would both be considered to be close enough to be 2. If X is 0.01 then it needs to be between 1.9998 and 2.0002 to be close enough.
i'm doing some exercises in my Java book. I'm very new to programming. Therefore, notice (in the code) that i'm still on Chapter one. Now I already did everything, I just want a confirmation if this is legitimate so I can feel free to move on next.
If not, I would sincerely appreciate to not do my code for me; I want advice.
Here's the question written in the book,
"Write an application that prompts/reads the numerator and denominator of a fraction as integers, then prints the decimal equivalent of the fraction."
I'll illustrate this sentence with my code:
I did a revision here. Is this one OK?..
import java.util.*;
public class ExerciseEleven {
public static void main (String[] args) {
Scanner sc = new Scanner (System.in);
double fraction;
int fractionValue;
int decimal;
double value;
System.out.println("Enter Numerator: ");
int numerator = sc.nextInt();
System.out.println("Enter Denominator: ");
int denominator = sc.nextInt();
fraction = (double) numerator / denominator;
fractionValue = (int) (fraction * 10);
decimal = fractionValue % 10;
value = decimal * 0.1;
System.out.println(value);
}
}
It compiles and works fine.
Thank you.
It doesn't do what task says it should. You read doubles instead of integers, and the decimal equivalent is not what you print out. Decimal equivalent for 1/2 is 0.5. And you print 5.
Also, you can pay attention to your code style: variable names are usually written in lowerCamelCase, like that : simpleVariable.
Update
now it prints what you need. However you do it not in the very right way and your indentation can still be improved.
It's fine (I didn't read the assignment very well, did I? Kudos to Vladimir.) ...but some comments:
Usually you want to indent methods within the class.
Standard practice is to use initial caps (Numerator) only for types (e.g., classes, interfaces, enums). Variable, field, and method names should start with a lower-case letter. Now, you're free to ignore standard practice, but if you do people will have a lot of trouble reading your code. :-)
For rounding, you probably want to look at Math.round rather than truncating with a cast. But the assignment didn't say anything about rounding.
You might want to handle the case where denominator is zero.
So keeping those in mind:
import java.util.*;
public class ExcerciseEleven {
public static void main (String[] args) {
Scanner sc = new Scanner (System.in);
System.out.println("Enter Numerator: ");
int numerator = sc.nextInt();
System.out.println("Enter Denominator: ");
int denominator = sc.nextInt();
if (denominator == 0) {
System.out.println("Can't divide by zero");
}
else {
double fraction = (double)numerator / denominator;
System.out.println(fraction);
}
}
}
Hey I am doing some thinking about this and I have noticed something interesting after looking at this source and here is the Algorithm that I plan on implementing
First I will convert the number from the Metric using the
Javax.Measure family of functions and I will get a number like
0.3750
Then I will divide the number by ONE_SIXTEENTH which = 0.0625
ONE_SIXTEENTH = 0.0625
The answer 0.3750 / ONE_SIXTEENTH = 6;
So now I know there are 6 sixteenths of the inch
Next I check to see if 6 is divisible by 4, 6/4 = 1.5 ie not a whole number so the fraction is still regarded as 6/16th of an inch for now
Next I check to see if 6 is divisible by 2, 6/2 = 3
This is a whole number so we will use it to reconstitute the fraction
So now that we have divided 6 by 2 and gotten 3 the 16 needs to be divided by 2 and we end up with 8 so 6/16th of an inch becomes 3/8th of an inch.
PS Has anyone noticed that this is similar to a fizz bang program?
____________________________________________
Here is the chart which helped me get my head around this
My workings
There are three important parts of division operation :
Sign of the result.
Integral part
Decimal part
Also, there are few corner cases where you need to deal with the fact that Integer.MIN_VALUE is greater than Integer.MAX_VALUE when compared in absolute form.
For example : -2147483648/-1 can't yield 2147483648 when divided in the form of integer types. The reason is simple. The type of the resulting type will be integer type, and the maximum positive value that a integer type variable can hold is +2147483647
To mitigate that scenario, we should at first convert both the numerator and denominator into their long positive form. That gives us the integral part of the answer.
The XOR of two numbers will have the sign bit as 1 only in case they have opposite signs. That solves the first part (sign of result) of the problem.
For decimal part, we can employ the general division rule i.e. multiply the remainder with 10 and try dividing again and repeat. Keep record of the remainder we have already come across to prevent the loop from going into unbounded iterations.
public String fractionToDecimal(int A, int B) {
StringBuilder sb = new StringBuilder((A^B) < 0 ? "-" : "");
long a = Math.abs((long)A);
long b = Math.abs((long)B);
sb.append(Long.toString(a/b));
long rem = a % b;
sb.append((rem != 0) ? "." : "");
Map<Long, Integer> remainderMap = new HashMap<>();
int pos = 0;
while (rem != 0){
sb.append(Long.toString((rem*10)/b));
remainderMap.put(rem, pos++);
rem = (rem*10) % b;
if (remainderMap.containsKey(rem)){
String currNum[] = sb.toString().split("\\.");
return currNum[0] + "." + currNum[1].substring(0, remainderMap.get(rem)) +
"(" + currNum[1].substring(remainderMap.get(rem)) + ")";
}
}
if (sb.toString().equals("-0")) return "0";
return sb.toString();
}
Sample output :
2/3 gives 0.(6)
-2147483648/-1 gives 2147483648