I have an array of floats and I would like to convert it to an array of doubles in Java. I am aware of the obvious way of iterating over the array and creating a new one. I expected Java to digest a float[] smoothly where it wishes to work with double[]... but it can not work with this.
What is the elegant, effective way of doing this conversion?
Basically something has to do the conversion of each value. There isn't an implicit conversion between the two array types because the code used to handle them after JITting would be different - they have a different element size, and the float would need a conversion whereas the double wouldn't. Compare this to array covariance for reference types, where no conversions are required when reading the data (the bit pattern is the same for a String reference as an Object reference, for example) and the element size is the same for all reference types.
In short, something will have to perform conversions in a loop. I don't know of any built-in methods to do this. I'm sure they exist in third party libraries somewhere, but unless you happen to be using one of those libraries already, I'd just write your own method. For the sake of convenience, here's a sample implementation:
public static double[] convertFloatsToDoubles(float[] input)
{
if (input == null)
{
return null; // Or throw an exception - your choice
}
double[] output = new double[input.length];
for (int i = 0; i < input.length; i++)
{
output[i] = input[i];
}
return output;
}
In Java 8 you can, if you really want to, do:
IntStream.range(0, floatArray.length).mapToDouble(i -> floatArray[i]).toArray();
But it's better (cleaner, faster, better semantics) to use Jon Skeet's function.
Do you actually need to copy your float array to a double array? If you are having trouble with the compiler and types when using the floats you can use this...
float x = 0;
double d = Double.valueOf(x);
What advantage do you get by taking a copy? If you need greater precision in the results of computations based on the floats then make the results double. I can see quite a lot of downsides to having a copy of the array, and performing the copy function, especially if it is large. Make sure you really need to do it.
HTH
Related
Through my humble experience in programming I can tell with 90% certainty that it would not be possible to do such a thing. However I know that you guys out there are more experienced than me and thus have better and more elegant solutions to my problem.
Here is my question:
I have made a class method to check for matrix addition or subtraction compatibility. It returns true if two given matrices are compatible for addition or subtraction. My next method is addMatrices which takes two matrices as follows:
double [][] addMatrices(double matA [][], double matB[][])
so the method return a 2d array here is my code solution:
double [][] addMatrices(double A [][], double B[][]){
double reusltMat;
if(AddSubComp(A,B){
resultMat= new double [A.getRows][A.getCols];
//getRows returns the # of crows
for (int i=0;i<A.getRows;i++)
for(int j= 0;j<A.getCols;j++)
reslutMat[i][j]=A[i][j]+B[i][j];
return resultMat;
else
System.out.println("Out of boundaries");
resultMat= new double[0][0];
return resultMat;
so my question is there any possible way to avoid initialising the resultMat if the if (statement)is false? so that I return a 2D array IFF the addition is compatible i.e the two given matrices are of the same dimensions.
Thank you for your time.
Did you tried returning null?
double[][] reusltMat = null;
After the else
return resultMat;
One way could be to use the Optional introduced in Java 8. It is built for such cases. Returning null is not the best solution particularly in view of the ugly nullpointer exceptions that arise because of it.
See here : Java 8 Optional.
Ask me if you need anything else.
I want to define a grid in which I specify an (x,y) coordinate for each point in the grid. So I want to do something like this:
int [][] pt;
for (x=0; x<numX; x=x+1) {
for (y=0; y<numY; y=y+1) {
pt[x][y] = {xval, yval};
}
}
The reason why is because I am mapping the values of an orderly grid to a disorderly grid. The above code of course causes an exception (unexpected token "{").
What is the best way to do what I'm trying to do? Thanks.
Two things:
You havent initialized your array (maybe you did just didnt put in code)
You are trying to put two values into a place where only one can be held.
Initialize your array like this (if you didnt)
int[][] pt = new int[numX][numY];
To store both values in the array you will need to use an object. The java Point class would be an example of something you could use
Point[][] pt = new Point[numX][numY];
for (x=0; x<numX; x=x+1) {
for (y=0; y<numY; y=y+1) {
pt[x][y] = new Point(xval, yval);;
}
}
You basically want to store a fixed number of values inside every array cell?
Then you are limited with 2 major cases:
Use an object
Java doesn't have user defined value types, so you are forced to use full-blown objects on the heap (with little hope that JVM will be very clever and optimize it, but chances are near zero), be it an array, or any other class.
If both of your values are less than 64 bits, you can pack them in built-in primitive type (such as long) using bitwise arithmetic. (You must be very careful here)
ints are 32 bit, so you can pack 2 ints in 1 long.
pt[x][y] = {xval, yval} is illegal, pt[][] is a double dimensional array. It only can store one value. Just like this pt[x][y] = value
You may try java map.
I sometimes tend to use (double)(long)(a*b/c) to store the integer part of the result as double. This works well for negative numbers too.
Is there any better way to achieve the same thing as I believe typecasting is a costly operation.
Please note I'm looking for Integer part of the number and not the rounded value.
For eg :
MyObj.setDouble((double)(long)(522.99))
MyObj.getDouble() returns 522.0 and not 523.0
Thanks.
Try Math.rint(double) or Math.round(double). Regardless of performance differences it's at least more clear and concise.
[Edit]
In response to your clarified question - "how do I get the integer part of a double without casting" (despite your title asking about rounding), try this:
public static double integerPart(double d) {
return (d <= 0) ? Math.ceil(d) : Math.floor(d);
}
integerPart(522.99); // => 522d
integerPart(-3.19); // => -3d
Of course, this form is likely no faster than casting since it's using a comparison and a method call.
Performance is not an issue here. But code (double)(long)(a*b/c) is ugly. You actually do not need casting at all if you assign the result to `double variable:
double d = a*b/c; exactly the same as double d = (double)(long)a*b/c;
You actually never need to perform casting when moving from lower to upper types. It is correct for primitives (e.g. int -> double) and for classes (e.g. ArrayList -> List).
What about Math.floor(double) I cant see the difference between integer part and rouding it down.
(Apologies if this has been asked before - I can't believe it hasn't, but I couldn't find one. Perhaps my search-fu is weak.)
For years I've "known" that Java has no native function to scale an array (i.e. multiply each element by a constant). So I've been doing this:
for (int i=0; i<array.length; i++) {
array[i] = array[i] * scaleFactor;
}
Is this actually the most efficient way (in this application, for example, it's an array of around 10000 doubles)? Or is there a better way?
Looks absolutely fine to me. I can't think of a more efficient way. Obviously try to put that code in one place rather than having the actual code all over the place, but other than that, no obvious problems.
Only other suggestion I can offer is to lazily scale whereby you only pay the cost of multiplication on accessing each element; e.g.
public class MyArray {
private final double[] arr;
private double scale = 1.0;
public MyArray(double[] arr) {
this.arr = arr;
}
public double getScale() {
return scale;
}
public void setScale(double scale) {
this.scale = scale;
}
public double elementAt(int i) {
return arr[i] * scale;
}
}
Obviously this is only better in certain situations:
When your array is huge AND
You are only accessing a few elements AND
You are typically accessing these elements once.
In other situations it's a micro-optimisation with no real benefit on modern CPUs.
The "better way" is to write array[i] *= scaleFactor; instead of array[i] = array[i] * scaleFactor;. :-)
Really, that's just syntactic sugar though - the compiled output (and hence performance) should be exactly the same. As Jon says, you're not going to be able to get any better performance, but personally I'll take a reduction in typing any day.
Only thing I can think to add in addition to Adamski and Jon Skeet is that if it happens to be an array of ints/longs and you're scaling by a power of 2, then you might get a slight improvement by using bitshift operators. YMMV though, since it will depend on the compiler (and possibly even the VM).
In Java 8:
double coef = 3.0;
double[] x1 = {1,2,3};
double[] x2 = DoubleStream.of(x1).map(d->d*coef).toArray();
System.out.println(Arrays.toString(x2));
output: [3.0, 6.0, 9.0]
You could work with threads, to reduce the runtime, but the bottom line is you would include this code and let each thread run a part of the for loop so the resulting program is as efficient as yours; it's just made faster
Looks optimal to me.
Don't fall for false optimisations like declaring the array length in a final field outside the loop. This works for Collections by avoiding repeat method calls to .size() and Strings avoiding method calls to .length() but on an array .length is already a public final field.
Also, looping backwards towards zero might be an assembly language optimisation but in a high level language like Java the VM will take care of any obvious tweaks.
Edit: As always, great answer in under 5 minutes :) Turns out if I make a tiny change - make the F capital in "float", I'll get the output I expected.
class NumberMachine{
public static void main(String [] args) {
Integer wi1 = new Integer("420");
int i = 101;
Integer wi2 = i*420/101;
if(wi1 == wi2) System.out.print(" ==");
if(wi1.equals(wi2)) System.out.print(" equal");
float f = 1.23f; //if this were Float f..., it'd print Float, not double.
new NumberMachine().printIt(f);
}
void printIt(Float f){
System.out.println(" Float");
}
void printIt(double d){
System.out.println(" double");
}
}
The output is equal double, which makes no sense to me. I expected equal Float. If I comment out the 2nd printIt, then that's indeed the output. I just don't know why, when faced with a choice between the two printIt, the compiler ignored the one whose parameter matched perfectly.
You get the result you do because boxing/unboxing was added late in Java's life and it was required that pre-existing code not be changed by the addition of the feature. So when you pass in a primitive float to printIt, it gets coerced to a primitive double, because the alternative would mean old (pre-JDK1.4) code would act differently, which was an unacceptable possibility for Sun.
Basically, think if this was pre-JDK1.4 code where boxing was not an alternative, no way could the primitive double get coerced to a java.lang.Float. Adding boxing can't be allowed to break that.
Reading the question it occurs to me from how you word it you may not see the difference between Float and float, because you refer to the change from capital F to lowercase F as a tiny change, when it really isn't so tiny. The lowercase version refers to a primitive numeric type, the uppercase version refers to an object that wraps the primitive numeric type, in order to allow numeric stuff to be used in general purpose things like collections. Prior to JDK1.4 if you wanted to do something like this you had to manually write a line like
myList.add(new Float(1.0F));
if you wanted to add a float value to a list. The addition of boxing/unboxing in JDK1.4 tried to paper over this and have the compiler do this for us, but unfortunately you still have to understand the difference between the two to make sense of what's going on.