Why java is converting number to negative before change of radix - java

In Java String Integer::toString(long i, int radix) returns representation of number i using given radix(base). Before it does conversion it is mapping number i to -i:
byte[] buf = new byte[65];
int charPos = 64;
boolean negative = (i < 0);
if (!negative) {
i = -i;
}
while (i <= -radix) {
buf[charPos--] = (byte)Integer.digits[(int)(-(i % radix))];
i = i / radix;
}
buf[charPos] = (byte)Integer.digits[(int)(-i)];
I do not understand why it works with negative number instead of positive. In Java x % y = -((-x) % y) so it is confusing to me because it should not do any difference because result of modulo operation is negated in the code.

The code doesn't want to handle positive and negative values differently, so it wants to unify the sign.
The most obvious normalization would be to convert negative value to positive. That's what we humans would do. But, with numbers stored in two's compliment, the value range of negative numbers it one larger than the value range of positive numbers, so if we normalized to positive, it would fail for -2147483648, aka Integer.MIN_VALUE.

Related

Trouble converting decimal value to binary

I'm making a program that converts decimal values to binary and vice versa. I've figured out how to convert binary to decimal, however I am having trouble with decimal to binary. I've seen many sources with code on how to do it but most of them involve using an array. I can't use an array because this program has a GUI and JLabel can't print the array. I've found a code that works with certain numbers, but doesn't with others. Here's the code:
public void convertBinary (int decimal)
{
String binary = "";
int remainder;
while (decimal != 0)
{
remainder = decimal % 2;
decimal /= 2;
binary += remainder;
}
lblDecBinAns.setText(String.valueOf(binary));
}
The given number is inputted by the user ("decimal") which is taken when they press the button. I don't know if there's an adjustment that can be made to this code for it to work properly. Perhaps there's an entirely different algorithm that would work for this or maybe a way to print an array with JLabel. I've been stumped on this for a while so any help is appreciated. Thanks.
P.S.
I'm aware of the .toBinary function, but I must create my own method for this one.
You got it done, the only thing you are missing is to REVERSE the binary string
int decimal=10;
String binary = "";
int remainder;
while (decimal != 0)
{
remainder = decimal % 2;
decimal /= 2;
binary += remainder;
}
System.out.println(new StringBuilder(binary).reverse().toString());
yelds
1010 as result
You need to add remainder as binary = remainder + binary or reverse the string. And no need to use String.valueOf since it's already a string. And also consider the case when decimal is zero you need to send 0
public String convertBinary(int decimal) {
String binary = "";
int remainder;
if(decimal == 0) {
return "0";
}
while (decimal != 0) {
remainder = decimal % 2;
decimal /= 2;
binary = remainder + binary;
}
return binary;
}
For a different twist, you can also do it like this.
Initialize the result to an empty string.
Using the AND & operator, mask off the low order bit. You could also use the remainder % operator here too.
Convert the bit, 1 or 0, to a string and prepend it to the result string.
Right shift the number (decimal) by 1 bit so the next bit can be checked.
while(!(decimal>>>1) == 0)
continue the while loop until decimal == 0 (i.e. all 1 bits have been shifted out of the number).
public static String toBinary(int decimal) {
// intialize the string
String binary = Integer.toString(decimal&1);
while ((decimal>>>=1) != 0) {
binary = Integer.toString(decimal&1)+ binary;
// or binary = Integer.toString(decimal % 2) + binary;
}
return binary;
}
Have you tried this?
String test = Integer.toString(n, 2); //n is the number to convert and 2 the base (binary). In case you want an octal number, for example, just change the base to 8.
But using this will cause problem in case you want to reconvert that String into a number just like this:
int number = Integer.parseInt(test); //This will cause NumberFormatException.
To avoid the error, each char of test must be converted to a char
char digit = test.charAt(i);
Finally, convert each char to a individual String again
String converted = String.valueof(digit);
And now you can convert the new String into an int

why does modulus by a large number seem to give a wrong answer in Java

I am trying to find trailing numbers of zeros in a number, here is my code:
public class TrailingZeroes {
public static void bruteForce(int num){ //25
double fact = num; //25
int numOfZeroes = 0;
for(int i= num - 1; i > 1; i--){
fact = fact * (i);
}
System.out.printf("Fact: %.0f\n",fact); //15511210043330984000000000
while(fact % 10 == 0){
fact = fact / 10;
double factRem = fact % 10;
System.out.printf("Fact/10: %.0f\n",fact); //1551121004333098400000000
System.out.printf("FactRem: %.0f\n",factRem); // 2?
numOfZeroes++;
}
System.out.println("Nnumber of zeroes "+ numOfZeroes); //1
}
}
As you can see the fact%10
You use floating point data type illegally.
The float and double primitive types in Java are floating point numbers, where the number is stored as a binary representation of a fraction and a exponent.
More specifically, a double-precision floating point value such as the double type is a 64-bit value, where:
1 bit denotes the sign (positive or negative).
11 bits for the exponent.
52 bits for the significant digits (the fractional part as a binary).
These parts are combined to produce a double representation of a value.
For a detailed description of how floating point values are handled in Java, see the Section 4.2.3: Floating-Point Types, Formats, and Values of the Java Language Specification.
The byte, char, int, long types are [fixed-point][6] numbers, which are exact representions of numbers. Unlike fixed point numbers, floating point numbers will some times (safe to assume "most of the time") not be able to return an exact representation of a number. This is the reason why you end up with 11.399999999999 as the result of 5.6 + 5.8.
When requiring a value that is exact, such as 1.5 or 150.1005, you'll want to use one of the fixed-point types, which will be able to represent the number exactly.
As has been mentioned several times already, Java has a BigDecimal class which will handle very large numbers and very small numbers.
public static void bruteForce(int num) { //25
double fact = num;
// precision was lost on high i
for (int i = num - 1; i > 1; i--)
fact *= i;
String str = String.format("%.0f", fact); //15511210043330984000000000
System.out.println(str);
int i = str.length() - 1;
int numOfZeroes = 0;
while (str.charAt(i--) == '0')
numOfZeroes++;
System.out.println("Number of zeroes " + numOfZeroes); //9
}

How to convert decimal to a higher base and vice versa

As a programming assignment for my java CSC class I have written the following code to convert a number and its base to a decimal number and then to a desired number and base.
public static int baseten(int number,int basein){
int power = 0;
int baseten = 0;
while (number > 0) {
int finalDigit = number % 10;
int product = finalDigit*(int)Math.pow(basein, power);
baseten += product;
number = number / 10;
power++;
}
return(baseten);
}
public static String convert (int decimal, int baseout){
String result = "";
while (decimal > 0){
//if baseout
int remainder = decimal % baseout;
decimal = decimal / baseout;
result = remainder + result;
}
return(result);
}
The question is how to convert a number to a base higher than ten within this code? I assume maybe a char[], but I'm not very good with arrays right now and can't imagine what that might look like. I don't think I can use toString's or parseInt's. Any help would be appreciated. Thanks in advance.
You are almost there. What you could do is insert an if/else statement to determine whether the remainder is greater or equal to ten or not and act accordingly. If it isn't, do what you're doing right now. If it is, then you need to add a char to your string. This char must be (remainder-10) + 65, since 65 is capital A on the ascii table and you need to know how many digits above ten remainder is and add that to A. This could be simplified to simply adding 55, but that is less readable in my opinion. Then, just add that char to the string instead of adding the int.

Java get fraction method

I am trying to make a method that returns the fractional value of a decimal number.
//these are included in a class called 'equazioni'
private static long getMCD(long a, long b) {
if (b == 0)
{ return a; }
else
{ getMCD(b, a % b); }
}
public String getFraction(double a) {
String s = String.valueOf(a);
int decimali = s.length() - 1 - s.indexOf('.');
int den = 1;
for(int i = 0; i < decimali; i++){
a *= 10;
den *= 10;
}
int num = (int) Math.round(a);
long mcd = getMCD(num,den);
return String.valueOf(num/mcd) + "/" + String.valueOf(den/mcd);
}
These 2 methods works perfectly with most of values. For example with a 8.65 it returns a 173/20, or 78.24 it returns a 1956/25. It's called in this way:
equazioni eq = new equazioni(a,b,c);
jTextField4.setText("8.65= " + eq.getFraction(8.65));
I am having troubles with fractions like 2/3, 5/18, 6/45... because the denominator is divisible by 3 and so the fraction is a periodic number. How could I represent it?
My problem is also "How could I recognize that it's a periodic number?". I thought that I could something like this
int test = den % 3;
If the denominator is divisible by 3, then I have to generate a fraction in a particular way. Any suggestion?
If I correctly understood your question, I am afraid it does not have a complete solution. Since a float is stored with a finite number of bits, not all fractions can be represented, especially the ones that are not decimal numbers like 2/3. Even for decimal numbers, not all of them can be represented.
In other words, your method will never be called by the float representation of 2/3 as an input, since this representation does not exist. You might be called with 0.66666666 (with whatever the limit of digits would be in Java), but that is not 2/3...
See this link for more details about floating point representation in Java: http://introcs.cs.princeton.edu/java/91float/

Convert a float to int

Android Studio 0.5.2
Hello,
I have a random float value that I want to convert to an int.
The float could have a random number between -9.4182062E-9 to 9.593071E-8.
I just want to get the positive int number so if the number is negative i.e. -5.5115866E-8 it should just return 5. I have used the Math.abs for this.
I have tried the following:
int accel = (int)Math.abs(randomAccel);
However, accel keeps giving me a zero no matter what value randomAccel is.
Many thanks for any suggestions,
Your negative number -5.485747E-5 finish by E-5 meaning that it is -0.0000548574
So the absolute value is 0.0000548574.
So Math.abs(-0.0000548574) is 0.0000548574
(int)0.0000548574 is 0
result is 0
Are your sure your code is responding 0 no matter the value of random? Check the number you are trying to convert.
You should unit test your code with your values.
Your random number range has very small a magnitude (negative exponents) - importantly it is less than +/-1. When float is cast to int, all fractional parts are truncated, thus every number in your range, after setting the sign to positive, will result in 0 if cast to int.
It seems like you want to ignore the exponent of your numbers. One way to do that would be:
int accel = Integer.parseInt(String.valueOf(randomAccel).replaceAll("-?(\\d+).*", "$1"));
int accel = (int)Math.abs(randomAccel);
This line performs 3 steps
Get the absolute value of randomAccel
Cast the value to an int (floating point numbers are truncated)
Assign the int value to accel
Now lets look what happens when the input is in the range [-9.4182062E-9,9.593071E-
8] (By the way -5.485747E-5 is not in this range.)
Input value -9.4E-9 = -0.0000000094
1. -9.4E-9 converted to 9.4E-9
2. 9.4E-9 cast to int, fractional part is removed. Value is 0
3. 0 is assigned to `accel`
If you just want to most significant digit, you could multiply by 10^8 and see if that value is greater than 0, if it is then trucate, else multiply by 10 then truncate:
int accel = 0;
r = Math.abs( randomAccel ) * 100000000;
if( r >= 10 ) {/* error out of range */}
else if( r > 0 ) accel = (int)r;
else
{
r *= 10;
accel = (int)r;
}
import static java.lang.Math.*;
Convert part:
double input =-5.485747E-5; //for example
double tmp = abs(input);
tmp *= pow(10, abs(floor(log10(tmp))));
int out = (int) tmp;
System.out.println(out);
output:
5

Categories

Resources