This question already has answers here:
Integer division: How do you produce a double?
(11 answers)
Closed 7 years ago.
I have tried this in Javascript and have gotten my answers, but the answer I need must be more exact. I am trying to divide 1 by every number between 2 and 1000, and simply print them.
public static void main(String [] args) {
for (int i=2;i<=1000;i++){
double g = (1/i);
System.out.println(g); // print "1/1,2,3,4.....1000"
}
}
I haven't done Java in a while, so I forget my correct variable names.
Since both 1 and i are integers, integer division is being used. Either 1 or i need to be double in the 1/i section of your code so that integer division is not used. You can do something like 1.0/i or 1/((double) i) to ensure that float division is used instead.
replace 1 by 1.0D that will result into double
try this
public static void main ( String args[] ) {
for (int i=2;i<=1000;i++){
double g = (1.0/i);
System.out.println("1/"+ig);
}
output:
0.5
0.3333333333333333
0.25
0.2
0.16666666666666666
0.14285714285714285
0.125
.
.
.
.
I would do something like this (note you can have as many digits of precision as you like) utilizing BigDecimal.
public static void main(String[] args) {
java.math.BigDecimal ONE = java.math.BigDecimal.ONE;
// 50 digits of precision.
java.math.MathContext mc = new java.math.MathContext(50);
for (int i = 2; i <= 1000; i++) {
java.math.BigDecimal divisor = new java.math.BigDecimal(i);
java.math.BigDecimal result = ONE.divide(divisor, mc);
result.round(mc);
System.out.printf("%d/%d = %s\n", 1, i,
result.toString());
}
}
Related
Edit: This has to do with how computers handle floating point operations, a fact that every programmer faces once in a lifetime. I didn't understand this correctly when I asked the question.
I know the simplest way to start dealing with this would be:
val floatNumber: Float = 123.456f
val decimalPart = floatNumber - floatNumber.toInt() //This would be 0.456 (I don't care about precision as this is not the main objective of my question)
Now in a real world with a pen and a piece of paper, if I want to "convert" the decimal part 0.456 to integer, I just need to multiply 0.456 * 1000, and I get the desired result, which is 456 (an integer number).
Many proposed solutions suggest splitting the number as string and extracting the decimal part this way, but I need the solution to be obtained mathematically, not using strings.
Given a number, with an unknown number of decimals (convert to string and counting chars after . or , is not acceptable), I need to "extract" it's decimal part as an integer using only math.
Read questions like this with no luck:
How to get the decimal part of a float?
How to extract fractional digits of double/BigDecimal
If someone knows a kotlin language solution, it would be great. I will post this question also on the math platform just in case.
How do I get whole and fractional parts from double in JSP/Java?
Update:
Is there a "mathematical" way to "calculate" how many decimals a number has? (It is obvious when you convert to string and count the chars, but I need to avoid using strings) It would be great cause calculating: decimal (0.456) * 10 * number of decimals(3) will produce the desired result.
Update 2
This is not my use-case, but I guess it will clarify the idea:
Suppose you want to calculate a constant(such as PI), and want to return an integer with at most 50 digits of the decimal part of the constant. The constant doesn't have to be necessarily infinite (can be for example 0.5, in which case "5" will be returned)
I would just multiply the fractional number by 10 (or move the decimal point to the right) until it has no fractional part left:
public static long fractionalDigitsLong(BigDecimal value) {
BigDecimal fractional = value.remainder(BigDecimal.ONE);
long digits;
do {
fractional = fractional.movePointRight(1); // or multiply(BigDecimal.TEN)
digits = fractional.longValue();
} while (fractional.compareTo(BigDecimal.valueOf(digits)) != 0);
return digits;
}
Note 1: using BigDecimal to avoid floating point precision problems
Note 2: using compareTo since equals also compares the scale ("0.0" not equals "0.00")
(sure the BigDecimal already knows the size of the fractional part, just the value returned by scale())
Complement:
If using BigDecimal the whole problem can be compressed to:
public static BigInteger fractionalDigits(BigDecimal value) {
return value.remainder(BigDecimal.ONE).stripTrailingZeros().unscaledValue();
}
stripping zeros can be suppressed if desired
I am not sure if it counts against you on this specific problem if you use some String converters with a method(). That is one way to get the proper answer. I know that you stated you couldn't use String, but would you be able to use Strings within a Custom made method? That could get you the answer that you need with precision. Here is the class that could help us convert the number:
class NumConvert{
String theNum;
public NumConvert(String theNum) {
this.theNum = theNum;
}
public int convert() {
String a = String.valueOf(theNum);
String[] b = a.split("\\.");
String b2 = b[1];
int zeros = b2.length();
String num = "1";
for(int x = 0; x < zeros; x++) {
num += "0";
}
float c = Float.parseFloat(theNum);
int multiply = Integer.parseInt(num);
float answer = c - (int)c;
int integerForm = (int)(answer * multiply);
return integerForm;
}
}
Then within your main class:
public class ChapterOneBasics {
public static void main(String[] args) throws java.io.IOException{
NumConvert n = new NumConvert("123.456");
NumConvert q = new NumConvert("123.45600128");
System.out.println(q.convert());
System.out.println(n.convert());
}
}
output:
45600128
456
Float or Double are imprecise, just an approximation - without precision. Hence 12.345 is somewhere between 12.3449... and 12.3450... .
This means that 12.340 cannot be distinghuished from 12.34. The "decimal part" would be 34 divided by 100.
Also 12.01 would have a "decimal part" 1 divided by 100, and too 12.1 would have 1 divided by 10.
So a complete algorith would be (using java):
int[] decimalsAndDivider(double x) {
int decimalPart = 0;
int divider = 1;
final double EPS = 0.001;
for (;;) {
double error = x - (int)x;
if (-EPS < error && error < EPS) {
break;
}
x *= 10;
decimalPart = 10 * decimalPart + ((int)(x + EPS) % 10);
divider *= 10;
}
return new int[] { decimalPart, divider };
}
I posted the below solution yesterday after testing it for a while, and later found that it does not always work due to problems regarding precision of floats, doubles and bigdecimals. My conclusion is that this problem is unsolvable if you want infinite precision:
So I re-post the code just for reference:
fun getDecimalCounter(d: Double): Int {
var temp = d
var tempInt = Math.floor(d)
var counter = 0
while ((temp - tempInt) > 0.0 ) {
temp *= 10
tempInt = Math.floor(temp)
counter++
}
return counter
}
fun main(args: Array <String> ) {
var d = 3.14159
if (d < 0) d = -d
val decimalCounter = getDecimalCounter(d)
val decimalPart = (d - Math.floor(d))
var decimalPartInt = Math.round(decimalPart * 10.0.pow(decimalCounter))
while (decimalPartInt % 10 == 0L) {
decimalPartInt /= 10
}
println(decimalPartInt)
}
I dropped floats because of lesser precision and used doubles.
The final rounding is also necessary due to precision.
This question already has answers here:
How Does Modulus Divison Work
(19 answers)
Closed 5 years ago.
package PracticePackage;
public class whileLoop {
public static void main(String[] args) {
int i=1;
System.out.println("Quotient "+i/2);
System.out.println("Remainder "+i%2);
}
}
this is the fomula that Java uses to yield the remainder of its operands:
(a/b)*b+(a%b)
where a is the dividend and b is the divisor.
so in your case it's like:
int i = 1;
int b = 2;
int result = (i / b) * b + (i % b);
hence the result 1 rather than 0
1/2 = 0.5
you defined i as int
Integral division in java takes floor of the answer if the answer is a real number so 1/2 becomes 0, making 1%2 equal to 1
I hope that explains.
because integers are not real numbers so you get 1 as answer and the real part of remainder is ignored since you defined i as an integer
This question already has answers here:
How to avoid floating point precision errors with floats or doubles in Java?
(12 answers)
Closed 5 years ago.
I have the following code.
public class ToBeDeleted {
public static final float MAX_PHYSICAL_LENGTH = 100000000;
public static void main(String[] args) {
//100000000
float temp = 100000000 -4;
System.out.println(temp);
if (MAX_PHYSICAL_LENGTH == temp)
System.out.println("True statement");
else
System.out.println("False Statement");
}
}
The output of the above is
1.0E8
True statement
Now with the below code
public class ToBeDeleted {
public static final float MAX_PHYSICAL_LENGTH = 100000000;
public static void main(String[] args) {
//100000000
float temp = 100000000 -5;
System.out.println(temp);
if (MAX_PHYSICAL_LENGTH == temp)
System.out.println("True statement");
else
System.out.println("False Statement");
}
}
The output is
9.9999992E7
False Statement
The question is
Whats wrong with the first code snip. Is this not plain mathematics
as far as float is concerned?
Why does it then give the expected output on the second code snip.
A typical (i.e. IEEE754) float only has 23 bits of precision. The other bits are for the exponent and the sign. The lowest integer that you can't store exactly is 1 plus the 24th power of 2.
100000000 - 4 is indistinguishable from 100000000 - 0.
A Java double gives you 52 bits of precision, therefore enough space to store all integers exactly up to the 53rd power of 2.
For more details see Which is the first integer that an IEEE 754 float is incapable of representing exactly?
But if you need exact decimal accuracy, then use a decimal type.
This question already has answers here:
Is floating point math broken?
(31 answers)
Strange floating-point behaviour in a Java program [duplicate]
(4 answers)
Closed 4 years ago.
I want a create a array of values with a interval of 0.2
I used the code :
public class TrialCode {
public static void main(String[] args) {
float a = -1.0f, b = 0.2f;
for (int i = 0; i <10; i++) {
a = a + b;
System.out.println(a);
}
}
}
Now the output that i am getting is :
-0.8
-0.6
-0.40000004
-0.20000003
-2.9802322E-8
0.19999997
0.39999998
0.59999996
0.79999995
0.99999994
whereas the output I want is
-0.8, -0.6, -0.4, -0.2, 0, 0.2, 0.4, 0.6, 0.8, 1.0
What should I do ?
If you don't want floating-point arithmetic, then don't use floating-point types. Float and Double aren't the only non-integral Numbers in the Java core library. What you're doing calls for BigDecimal.
import java.math.BigDecimal;
public class TrialCode {
public static void main(String[] args) {
BigDecimal a = new BigDecimal("-1.0");
BigDecimal b = new BigDecimal("0.2");
for (int i = 0; i < 10; i++) {
a = a.add(b);
System.out.println(a);
}
}
}
Floating point numbers only work up to a certain precision. For float it is 6-7 significant digits, for double it is 15-16 significant digits. And due to the binary representation simple decimal fractions like 0.1 cannot be represented exactly.
You can round the output to get the results you want:
System.out.printf("%.1f", a);
You can use something like
new DecimalFormat("#.#").format(0.19999997); //"0.2"
I am trying to beautify a program by displaying 1.2 if it is 1.2 and 1 if it is 1 problem is I have stored the numbers into the arraylist as doubles. How can I check if a Number is a double or int?
Well, you can use:
if (x == Math.floor(x))
or even:
if (x == (long) x) // Performs truncation in the conversion
If the condition is true, i.e. the body of the if statement executes, then the value is an integer. Otherwise, it's not.
Note that this will view 1.00000000001 as still a double - if these are values which have been computed (and so may just be "very close" to integer values) you may want to add some tolerance. Also note that this will start failing for very large integers, as they can't be exactly represented in double anyway - you may want to consider using BigDecimal instead if you're dealing with a very wide range.
EDIT: There are better ways of approaching this - using DecimalFormat you should be able to get it to only optionally produce the decimal point. For example:
import java.text.*;
public class Test
{
public static void main(String[] args)
{
DecimalFormat df = new DecimalFormat("0.###");
double[] values = { 1.0, 3.5, 123.4567, 10.0 };
for (double value : values)
{
System.out.println(df.format(value));
}
}
}
Output:
1
3.5
123.457
10
Another simple & intuitive solution using the modulus operator (%)
if (x % 1 == 0) // true: it's an integer, false: it's not an integer
I am C# programmer so I tested this in .Net. This should work in Java too (other than the lines that use the Console class to display the output.
class Program
{
static void Main(string[] args)
{
double[] values = { 1.0, 3.5, 123.4567, 10.0, 1.0000000003 };
int num = 0;
for (int i = 0; i < values.Length; i++ )
{
num = (int) values[i];
// compare the difference against a very small number to handle
// issues due floating point processor
if (Math.Abs(values[i] - (double) num) < 0.00000000001)
{
Console.WriteLine(num);
}
else // print as double
{
Console.WriteLine(values[i]);
}
}
Console.Read();
}
}
Alternatively one can use this method too, I found it helpful.
double a = 1.99;
System.out.println(Math.floor(a) == Math.ceil(a));
You can use:
double x=4;
//To check if it is an integer.
return (int)x == x;