Double.MAX_VALUE is the maximum value a double can represent (somewhere around 1.7*10^308).
This should end in some calculation problems, if you try to subtract the maximum possible value of a data type.
Even though when you are dealing with money you should never use floating point values especially while rounding this can cause problems (you will either have to much or less money in your system then).
Answer from Kuchi on Stack OverflowDouble.MAX_VALUE is the maximum value a double can represent (somewhere around 1.7*10^308).
This should end in some calculation problems, if you try to subtract the maximum possible value of a data type.
Even though when you are dealing with money you should never use floating point values especially while rounding this can cause problems (you will either have to much or less money in your system then).
Resurrecting the dead here, but just in case someone stumbles against this like myself. I know where to get the maximum value of a double, the (more) interesting part was to how did they get to that number.
double has 64 bits. The first one is reserved for the sign.
Next 11 represent the exponent (that is 1023 biased). It's just another way to represent the positive/negative values. If there are 11 bits then the max value is 1023.
Then there are 52 bits that hold the mantissa.
This is easily computed like this for example:
public static void main(String[] args) {
String test = Strings.repeat("1", 52);
double first = 0.5;
double result = 0.0;
for (char c : test.toCharArray()) {
result += first;
first = first / 2;
}
System.out.println(result); // close approximation of 1
System.out.println(Math.pow(2, 1023) * (1 + result));
System.out.println(Double.MAX_VALUE);
}
You can also prove this in reverse order :
String max = "0" + Long.toBinaryString(Double.doubleToLongBits(Double.MAX_VALUE));
String sign = max.substring(0, 1);
String exponent = max.substring(1, 12); // 11111111110
String mantissa = max.substring(12, 64);
System.out.println(sign); // 0 - positive
System.out.println(exponent); // 2046 - 1023 = 1023
System.out.println(mantissa); // 0.99999...8
The maximum finite value for a double is, in hexadecimal format, 0x1.fffffffffffffp1023, representing the product of a number just below 2 (1.ff… in hexadecimal notation) by 21023. When written this way, is is easy to see that it is made of the largest possible significand and the largest possible exponent, in a way very similar to the way you build the largest possible long in your question.
If you want a formula where all numbers are written in the decimal notation, here is one:
Double.MAX_VALUE = (2 - 1/252) * 21023
Or if you prefer a formula that makes it clear that Double.MAX_VALUE is an integer:
Double.MAX_VALUE = 21024 - 2971
If we look at the representation provided by Oracle:
0x1.fffffffffffffp1023
or
(2-2^-52)·2^1023
We can see that
fffffffffffff
is 13 hexadecimal digits that can be represented as 52 binary digits ( 13 * 4 ).
If each is set to 1 as it is ( F = 1111 ), we obtain the maximum fractional part.
The fractional part is always 52 bits as defined by
http://en.wikipedia.org/wiki/Double-precision_floating-point_format
1 bit is for sign
and the remaining 11 bits make up the exponent.
Because the exponent must be both positive and negative and it must represent 0, it to can have a maximum value of:
2^10 - 1
or
1023
0B111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111 is an int literal, not double. Since it is bigger than Integer.MAX_VALUE, it doesn't compile.
If you want to get a double value from its binary representation, you should use Double.longBitsToDouble (and use a long literal instead of int):
double a = Double.longBitsToDouble(0B111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111L);
The largest double is not all bits '1', the format is the IEEE754. You can play around with a converter to see the effect of the individual bits: http://www.binaryconvert.com/convert_double.html
The maximum number you can represent with float or double is infinite. You can try this:
double my_max_double = Double.POSITIVE_INFINITY;
In the expression:
double randomDouble = Integer.MAX_VALUE + rand.nextInt((max - min) + 1);
the right hand side of the expression will first assign the sum to an integer, then this result will be cast to a double. Since adding anything to Integer.MAX_VALUE will result in overflow, you end up with a negative number, because the sign bit gets flipped as part of the overflow.
If you want a double, then just cast MAX_VALUE to double:
double randomDouble = (double)Integer.MAX_VALUE + (double)rand.nextInt((max - min) + 1);
Now in this case you get what you want, because you are adding a random number to a double, which is bearing the largest int value, which is not near the limit for what doubles can store.
Demo
To put it simply: when you execute double randomDouble = Integer.MAX_VALUE + rand.nextInt((max - min) + 1); the part that is actually overflowing (as an Integer, thus taking a negative value) is just Integer.MAX_VALUE + rand.nextInt((max - min) + 1) which is subsequently casted to double.
java.lang.Math class provides a max method to find maximum of two double inputs. Here is the signature:
public static double max(double a,
double b)
public static double userMax(double[] array) {
double maximum = array[0];
for (double d: array) {
maximum = Math.max(maximum, d);
}
return double;
}
Now after defining this function, you can call:
double toTheMax = userMax(numbers);
Method to do the checks yourself
public static double findMax(double[] data) {
double max = Double.MIN_VALUE;
for (double val : data) {
if (val > max) {
max = val;
}
}
return max;
}
Using the Math utility
public static double findMax2(double[] data) {
double max = Double.MIN_VALUE;
for (double val : data) {
max = Math.max(val, max);
}
return max;
}
Using streams
public static double findMax3(double[] data) {
return Arrays.stream(data).max().getAsDouble();
}
Doing your own checks
public static double findMin(double[] data) {
double min = Double.MAX_VALUE;
for (double val : data) {
if (val < min) {
min = val;
}
}
return min;
}
Using Math utility
public static double findMin2(double[] data) {
double min = Double.MAX_VALUE;
for (double val : data) {
min = Math.min(val, min);
}
return min;
}
Using streams
public static double findMin3(double[] data) {
return Arrays.stream(data).min().getAsDouble();
}
You can do everything you want do do in a single loop. First calculate the sum for each value and then check for that sum if it is a new maximum and/ or minimum value. If any of these option is true, update the respective maximum or minimum value.
import java.util.*;
public class Application {
public static void main(String[] args) {
var test = new double[]{10d, 4.43d, 5.3d, -6.8d, 7.1d, 8.7d, 8.1d, 234d, -3.9d, -455.3d};
minMaxSum(test);
}
public static void minMaxSum(double[] arr) {
double acc = 0;
// initialize the minimal value with the maximal value
double min = Double.MAX_VALUE;
// initialize the biggest value with the smallest possible value
double max = Double.MIN_VALUE;
var sum = new double[arr.length];
// a single for loop
for (int i = 0; i < arr.length; i++) {
var cur = arr[i];
// sum up adding the current value
acc += cur;
// save the current value in new array so we can verify the result (not actually required for the algorithm)
sum[i] = acc;
// if something is smaller than what we've already encountered => set new smallest value
if(acc < min) min = acc;
// if something is bigger than what we've already encountered => set new biggest value
if(acc < max) max = acc;
}
System.out.printf("""
Original: %s
Prefix-sum: %s
Min: %s
Max: %s
""", Arrays.toString(arr), Arrays.toString(sum), min, max);
}
}
Expected output:
Original: [10.0, 4.43, 5.3, -6.8, 7.1, 8.7, 8.1, 234.0, -3.9, -455.3]
Prefix-sum: [10.0, 14.43, 19.73, 12.93, 20.03, 28.73, 36.83, 270.83, 266.93, -188.37]
Min: -188.37
Max: 270.83
As many people recommended sorting as a viable approach, here some remarks on sorting. First, yes, it would give you a correct result but there is a price to pay which is speed and well it is just an unnecessarily complex solution.
Sorting based on comparisons and without any pre-conditions cannot be done faster than in O(n log n). It is obvious that the solution above needs O(n) time thus is a complexity class faster. Also the constants (which are ignored in big-O notation) are quite small in the above solution, so even if some pre-conditions were met and you could use a special sorting algorithm like Map sort (or alike) which run in O(n) (again: under certain conditions) the above solution would still be faster and, not to mention, much simpler. So don't make your life harder than it needs to be.
Try changing this:
double max = Double.MAX_VALUE;
double min = Double.MIN_VALUE;
to this:
double max = -Double.MAX_VALUE;
double min = Double.MAX_VALUE;
After all, if you start off thinking you've already seen MAX_VALUE as the highest, you're never going to see anything greater than that, are you?
EDIT: Note the use of -Double.MAX_VALUE here, instead of Double.MIN_VALUE. MIN_VALUE is the smallest positive number, whereas I assume you really want "the most strongly negative finite value".
You want the first value you read to replace both max and min. An alternative would be to use Double instead, to represent the "missing" value with null to start with:
Double max = null;
Double min = null;
if (max == null || mag > max)
{
max = mag;
}
// Ditto for min
As a style issue, I'd also only compute the average after you've read the whole of the input - you're repeatedly overwriting the value for no reason. The only reason not to do this is to avoid having to think about the case where count is 0 (i.e. an empty file) but I'd personally handle that separately anyway - when you have no values, there simply isn't an average.
dont use Double.MIN_VALUE its not what you expect it to be
Double.MIN_VALUE its not a negative number Double.MIN_VALUE is a very small nummber its 4.9e-324; // 0x0.0000000000001P-1022
Comparing with it will break as soon as you use negative numbers
A small utility class i wrote to help with it:
public class MinMaxUtil<T extends Comparable<T>>
{
private T minimum;
private T maximum;
public MinMaxUtil()
{
reset();
}
public void check( T value)
{
if ( minimum == null || value.compareTo(minimum) < 0 )
minimum = value;
if ( maximum == null || value.compareTo(maximum) > 0 )
maximum = value;
}
public void check( T [] values )
{
for (T value : values)
{
check(value);
}
}
public void check( Collection<T> values )
{
for (T value : values)
{
check(value);
}
}
public T getMinimum()
{
return minimum;
}
public T getMaximum()
{
return maximum;
}
public void reset()
{
minimum = null;
maximum = null;
}
@Override
public String toString()
{
return "MinMaxUtil{"+
"minimum="+minimum+
", maximum="+maximum+
'}';
}
}
The number that you're looking for is 9,007,199,254,740,991 because 9,007,199,254,740,991 + 1 = 9,007,199,254,740,992 but 9,007,199,254,740,992 + 1 = 9,007,199,254,740,992.
I found this experimentally using the following snippet.
double a = 9.007199254E15;
while (a + 1 > a) {
a += 1;
}
System.out.println(a);
Given the fact that you are using this value as a counter, and that the maximum value for longs is 2^63 - 1 = 9.22E18 (as Peter pointed out), there seems to be no reason not to use longs instead.
I need to use double as a counter and want to know where is the upper limit of the reliable counting.
I can't imagine why you would use a double as a counter to store an integer, but the limit is in the range of eight million billion (2^53). If you use a long as a counter the limit is 9 billion billion.
You can use ArrayList<Double> and than
ArrayList<Double> alist=new ArrayList<Double>();
//Add double values to this list
You can use Collections.max(alist) to get maximum value and Collections.min(alist) to get minimun value.
In Java 8:
Arrays.stream(darray).max().getAsDouble()
Full method (in our case, return zero if the array is empty; change your default as desired).
public static double max(final @Nullable double... values)
{
return ((values != null) && (values.length > 0)) ? Arrays.stream(values).max().getAsDouble() : 0;
}
This method can be called with either an array or varargs parameter:
double[] darray = new double[]{43.7, 65.2, 99.1, 87.6};
double max1 = max(darray);
double max2 = max(1.2, 3.4, 5.6);
The int range issue is because you have an int literal. Use a double literal by postfixing 'd':
public static void main(String[] args) {
assignDoubleToInt(2147483646); // One less than the maximum value an int can hold
assignDoubleToInt(2147483647); // The maximum value an int can hold
assignDoubleToInt(2147483648d);// One greater than the maximum value an int can hold. Causes error and does not
// run.
}
I believe your equality test should be <=, also: "if the value in d is not larger than the maximum value for an int" - so if it is EQUAL to the maximum value for an int, it's valid:
public static void assignDoubleToInt(double d) {
int i = 0;
if (d <= Integer.MAX_VALUE)
i = (int) d;
System.out.println(i);
}
Integer.MAX_VALUEholds2147483647. I am assuming this is the maximum value an int can hold?
Yes.
throws
"The literal 2147483648 of type int is out of range."
You can't create an int literal representing a number outside of the int range, so 2147483647 is legal but 2147483648 is not. If you want a larger integer literal, use a long literal, with the letter L appended: 2147483648L, or a double literal with a decimal point (or D appended): 2147483648.0 (or 2147483648D).
is not the proper way to do this.
The comparison d < Integer.MAX_VALUE is legal and correct, because Integer.MAX_VALUE will be widened to a double for the comparison, and a double can be (much) larger in value than Integer.MAX_VALUE. You just need to make sure you can pass the proper value in as detailed above.
(As noted in a comment above, it should be d <= Integer.MAX_VALUE, with <=.)
See https://docs.oracle.com/javase/8/docs/api/java/lang/Double.html
Double.MAX_VALUE is the biggest finite number that double can hold. (A very large positive number.)
Double.MIN_VALUE is the smallest positive number that double can hold. (A very small positive number.)
So -Double.MAX_VALUE is a very large negative number. That's a lower number than a very small positive number.
Contrarily, Integer.MIN_VALUE is the most negative number that an int can hold. It has a different meaning from the similarly named constant in Double.
As stated in the Javadoc of Double:
MAX_VALUEis "A constant holding the largest positive finite value of type double, (2-2-52)·21023.", that is, a large positive number.MIN_VALUEis "A constant holding the smallest positive nonzero value of type double, 2-1074.", that is, a small positive number.
So, -MAX_VALUE is a large negative number, which is less that zero, which is less than a small positive number.small positive number.
While others already have answered why Math.max is not variadic, they didn't answer why such a method is not created when variadic functions are introduced.
I even don't know it (there is an open bug-report) so I can only guess:
It is true that it is not implemented in Math, but if we look into Collections there is the following method:
public static <T extends Object & Comparable<? super T>> T max(
Collection<? extends T> coll) {
...
}
While the type signature looks ugly (it needs to be flexible enough to handle covariance and contravariance), it can easily be used with Collections.max(Arrays.asList(-13, 12, 1337, 9)); After all the function is implemented, just in a different place.
Even better: This method can handle not only doubles, but all types implementing the Comparable interface.
Nevertheless neither your suggested solution, nor the solution in Collections is object oriented, they are just static methods. Luckily with JDK8 this will change:
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
int max(List<Integer> list) {
Optional<Integer> opt = list.stream().max((a,b) -> a-b);
return opt.orElse(Integer.MAX_VALUE);
}
max(Arrays.asList(-13, 12, 1337, 9)); // 1337
max(Arrays.asList()); // 2147483647
For the upcoming release the collection library is reworked in Project Lambda to be more object oriented. In the example above, Lambdas are used to provide an easy and readable way to determine the max element. The following would work too:
import static java.util.Comparators.naturalOrder;
Arrays.asList(-13, 12, 1337, 9)
.stream()
.max(naturalOrder())
.ifPresent(System.out::println); // 1337
Instead of max one could also use the higher order function reduce:
Arrays.asList(-13, 12, 1337, 9)
.stream()
.reduce((a,b) -> a > b ? a : b)
.ifPresent(System.out::println); // 1337
Another detail is the use of Optional. It is a type to simplify error handling due to composition of higher order functions as shown in the examples above.
The lambda proposal has several advantages that make it unnecessary to implement a variadic form of Math.max:
- It is object oriented
- It is polymorphic. This means it can be used with every type of collection (
List,Set,Stream,Iteratoretc.) - It is expressive and easy to understand
- It allows on-the-fly parallelization. Just change
.stream()to.parallelStream()
The java.lang.Math has been introduced in JDK 1.0, long before variadic functions were introduced into the language in Java 5.
In addition, efficiency is a concern: if you need two elements most of the time, it is much faster to pass them "inline", without creating an intermediate array to hold them. This also avoids the costs of setting up a loop inside the implementation.