0

Let's say, using java, I type

double number;

If I need to use very big or very small values, how accurate can they be? I tried to read how doubles and floats work, but I don't really get it.

For my term project in intro to programming, I might need to use different numbers with big ranges of value (many orders of magnitude).

Let's say I create a while loop,

while (number[i-1] - number[i] > ERROR) {
     //does stuff
}

Does the limitation of ERROR depend on the size of number[i]? If so, how can I determine how small can ERROR be in order to quit the loop?

I know my teacher explained it at some point, but I can't seem to find it in my notes.

Ousmane D.
  • 54,915
  • 8
  • 91
  • 126
A name
  • 3
  • 1
  • 5
  • I think, that it is better to use BigDecimal instead of double if you want to get exact result and avoid cases with double rounding issue – Arthur Kushner May 07 '17 at 21:04
  • Possible duplicate of [Large Numbers in Java](http://stackoverflow.com/questions/849813/large-numbers-in-java) – Remus Rusanu May 07 '17 at 21:04
  • *"I tried to read how doubles and floats work, but I don't really get it."* Well what don't you get? How are we supposed to explain the answer if you don't understand it? – Radiodef May 07 '17 at 21:04
  • Study _What Every Computer Scientist Should Know About Floating-Point Arithmetic_, https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html – Lew Bloch May 07 '17 at 21:35
  • @ArthurKushner How would you calculate 1/3 in BigDecimal without rounding? – Patricia Shanahan May 07 '17 at 22:26
  • One way to get the general concept of floating point is to think about scientific notation with a fixed number of digits. The relative error is similar regardless of magnitude. The absolute error increases with magnitude. – Patricia Shanahan May 07 '17 at 22:28
  • @PatriciaShanahan, with BigDecimial you can manage rounding. And with doubles simple math operation can give unexpected result: double total = 0; total += 5.6; total += 5.8; System.out.println(total); result: 11.399999999999999 Actually the result is not unexpected if you understand what actually happens under the hood, but if you not familiar with that - it can bring you some headache – Arthur Kushner May 07 '17 at 22:46
  • @ArthurKushner I still want to know how to avoid rounding when calculating 1/3 in BigDecimal. To me, it seems no different from the rounding you get when calculating 56/10 + 56/10 in double. – Patricia Shanahan May 07 '17 at 22:52
  • @PatriciaShanahan, if you carefully read my previous message, i said that you can manage the process of rounding with BigDecimial. And i didn't say that there is no rounding with this class. – Arthur Kushner May 07 '17 at 23:29

3 Answers3

2

If you don't tell us what you want to use it for, then we cannot answer anything more than what is standard knowledge: a double in java has about 16 significant digits, (that's digits of the decimal numbering system,) and the smallest possible value is 4.9 x 10-324. That's in all likelihood far higher precision than you will need.

The epsilon value (what you call "ERROR") in your question varies depending on your calculations, so there is no standard answer for it, but if you are using doubles for simple stuff as opposed to highly demanding scientific stuff, just use something like 1 x 10-9 and you will be fine.

Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
  • 1
    I want to use it to find the magnetic field of a solenoid, but yeah, I think it should be enough lol – A name May 07 '17 at 21:22
  • Computations of magnetic fields do involve extremely small quantities, so be aware of the fact that you only have 16 significant digits, which means that all your calculations must fall within the same 16 orders of magnitude. It is not advisable to be working with huge numbers and small numbers at the same time. (I.e. don't try to mix nanometers with megaparsecs.) – Mike Nakis May 07 '17 at 21:37
2

Does the limitation of ERROR depend on the size of number[i]?

Yes.

If so, how can I determine how small can ERROR be in order to quit the loop?

You can get the "next largest" double using Math.nextUp (or the "next smallest" using Math.nextDown), e.g.

double nextLargest = Math.nextUp(number[i-1]);
double difference = nextLargest - number[i-1];

As Radiodef points out, you can also get the difference directly using Math.ulp:

double difference = Math.ulp(number[i-1]);

(but I don't think there's an equivalent method for "next smallest")

Community
  • 1
  • 1
Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • 2
    You can also use `Math.ulp(double)` which returns the positive distance between a number and the next largest magnitude, i.e. basically what you're doing with the subtraction. – Radiodef May 07 '17 at 21:20
  • 1
    Feel free to add it to your answer, if you want. – Radiodef May 07 '17 at 21:28
0

Both the float and double primitive types are limited in terms of the amount of data they can store. However, if you want to know the maximum values of the two types, then run the code below with your favourite IDE.

System.out.println(Float.MAX_VALUE);
System.out.println(Double.MAX_VALUE);
  • double data type is a double-precision 64-bit IEEE 754 floating point (digits of precision could be between 15 to 17 decimal digits).
  • float data type is a single-precision 32-bit IEEE 754 floating point (digits of precision could be between 6 to 9 decimal digits).

After running the code above, if you're not satisfied with their ranges than I would recommend using BigDecimal as this type doesn't have a limit (rather your RAM is the limit).

Ousmane D.
  • 54,915
  • 8
  • 91
  • 126
  • thanks my teacher said not to use IDE while i just started learning, so do everything on notepad++ for now – A name May 07 '17 at 21:20