I use code like:
Double getabsValue(final Object[] value){
if (value==null) return null;
if (value.lengt==0) return null;
final Double absValue=Maths.abs(value[0]);
if (absValue>0) return absValue
else return null;
But in my application I have problem with performance.
How it can be optimized?
Maybe better use?
if (absValue>0) return absValue
else return absValue<0?-absValue:null;
Thanks
Well, the code you've got at the moment won't even compile - there's no Math.abs(Object) call as far as I'm aware. However, assuming you actually have a cast to Double there, you're going to be boxing all the time. You could avoid boxing when the value is already greater than 0, and avoid the call when the value is 0, like this:
static Double getAbsValue(Object[] values) {
if (values == null || values.length == 0) {
return null;
}
Double value = (Double) values[0];
return value > 0 ? value
: value == 0 ? null
: -value;
}
By the time we get to the final option, we already know that the value is negative, so we don't really need the call to abs any more.
It's not really clear what the context is here. You say you've got a performance problem, but is it definitely in this code?
EDIT: Your latest code shows:
if (absValue>0) return absValue
else return -1*absValue;
That doesn't do the same thing - it doesn't return null if the array contains a boxed 0 value, as your original code does.
You should focus on correctness before performance.
What do you want your code to do with an input of 0? If you want it to return 0, then I would use:
return value >= 0 ? value : -value;
If you want it to return null, use the code I provided originally.
Why include a multiplication by -1 rather than just use the unary negation operator, by the way? I would expect either the compiler or the JIT to get rid of that anyway, but fundamentally you don't want to be performing multiplication - you want to perform negation. Make your code read as closely as possible to how you'd describe your aims.
I use code like:
Double getabsValue(final Object[] value){
Why?
The first thing I would do with this is redefine the signature.
It is pointless to specify Object[] when it basically has to be a Double[], or at least an Object[] which contains Doubles, otherwise it will throw a ClassCastException.
Why specify an array when you only use the first element?
Why a Double when what you really need is a double?
So I would redefine it it to take a single argument of type double. That moves the overhead of getting things out of the array back to the caller where he can see it. He may not even have an array, so he would have to construct it to call this method. And he may already have a double not a Double, in which case again he or the compiler would have to box it into a Double.
The second thing I would do with it is review what's left after this change. The change gets rid of the null and length checks, and the typecast, so all you are left with is return Math.abs(d); So it becomes clear that the entire method is basically pointless.
So the third thing I would do with it is delete it.
Related
Hey guys I'm currently working with talend and have to calculate some KPI's.
I'm getting the ArithmeticException: Division by zero every time now even if I follow the same schema in different calculations and they work without problems.
(((functions_pattern.checkIfNull(opportunities1.tatsaechlicherumsatz)) ==
BigDecimal.ZERO) || ((functions_pattern.checkIfNull(rechnung1.netto)) ==
BigDecimal.ZERO))
? BigDecimal.ZERO
: (rechnung1.netto.divide(opportunities1.tatsaechlicherumsatz ,
java.math.MathContext.DECIMAL32))
functions_pattern.checkIfNull sets a null value to zero (in this case BigDecimal.ZERO) I also tried various variations on this (separate null checking etc.)
Also since I'm working with talend I have to use ternary operators.
Using == to test a BigDecimal is a bad idea.
Even assuming that checkIfNull returns Decimal.ZERO when null, you still have the problem that rechnung1.netto could have been a zero that is != Decimal.ZERO.
Also equals has the problem that both the value and the scale must be equal for two BigDecimal values to be considered equal.
This is the safe way to test a (non-null) BigDecimal value for zero:
BigDecimal x = ...
if (x.compareTo(BigDecimal.ZERO) == 0) {
// it is zero
} else {
// it is not zero
}
I can't seem to figure out how to test a number to see if it's zero. Couldn't someone please tell me what I'm missing.
getMin = Number.class
getMax = Number.class
Test
Number value = mvFacet.getMin() > 0 ? mvFacet.getMin() : mvFacet.getMax();
System.out.println(value.toString());
Number num;
...
if(num.intValue() == 0) {
// num is 0 so do something here
}
Other methods available on Number are:
byteValue()
doubleValue()
floatValue()
longValue()
shortValue()
Select whichever method makes the most sense for the values you are using.
To add to Jason's answer, if you're going to use num.doubleValue() then don't use == since it doesn't handle edge cases like when the double value is NaN or Infinity. Please use Double.compare(num.doubleValue(), 0.0);.
In a column(quantity) I have some values of type double and N/A too.
In my comparator class compare method, this is the coding mentioned below
if(double1 == double2) {
return 0;
}
// We know that both aren't null, so if only long 2 is null, 1 > 2
if(double2 == null) {
return 1;
}
// We know that both aren't null, so if only long 1 is null, 1 < 2
if(double1 == null) {
return -1;
}
// Nulls are handled, use the native compare
return double1.compareTo(double2);
double1 and double2 is of type Double.
It gives Exception: java.lang.NumberFormatException: For input string: "N/A" .
Please give me the solution.
It's my guess (I can't really say without seeing how you're using these Doubles) that you're looking to hold a value that doesn't really exist, and a value that may.
To that end, I would say that you construct your Double with Double.NaN as so:
Double double1 = new Double(Double.NaN);
I'm not sure if NaN is defined for a sorting operation - it holds no intricate order since it's just not a number. You may want to use an auxiliary structure, such as a List<Double>, to first comb through the Doubles that aren't a number, and place them first. Then, you could sort the remaining Doubles.
Is there any way to find the absolute value of a number without using the Math.abs() method in java.
If you look inside Math.abs you can probably find the best answer:
Eg, for floats:
/*
* Returns the absolute value of a {#code float} value.
* If the argument is not negative, the argument is returned.
* If the argument is negative, the negation of the argument is returned.
* Special cases:
* <ul><li>If the argument is positive zero or negative zero, the
* result is positive zero.
* <li>If the argument is infinite, the result is positive infinity.
* <li>If the argument is NaN, the result is NaN.</ul>
* In other words, the result is the same as the value of the expression:
* <p>{#code Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))}
*
* #param a the argument whose absolute value is to be determined
* #return the absolute value of the argument.
*/
public static float abs(float a) {
return (a <= 0.0F) ? 0.0F - a : a;
}
Yes:
abs_number = (number < 0) ? -number : number;
For integers, this works fine (except for Integer.MIN_VALUE, whose absolute value cannot be represented as an int).
For floating-point numbers, things are more subtle. For example, this method -- and all other methods posted thus far -- won't handle the negative zero correctly.
To avoid having to deal with such subtleties yourself, my advice would be to stick to Math.abs().
Like this:
if (number < 0) {
number *= -1;
}
Since Java is a statically typed language, I would expect that a abs-method which takes an int returns an int, if it expects a float returns a float, for a Double, return a Double. Maybe it could return always the boxed or unboxed type for doubles and Doubles and so on.
So you need one method per type, but now you have a new problem: For byte, short, int, long the range for negative values is 1 bigger than for positive values.
So what should be returned for the method
byte abs (byte in) {
// #todo
}
If the user calls abs on -128? You could always return the next bigger type so that the range is guaranteed to fit to all possible input values. This will lead to problems for long, where no normal bigger type exists, and make the user always cast the value down after testing - maybe a hassle.
The second option is to throw an arithmetic exception. This will prevent casting and checking the return type for situations where the input is known to be limited, such that X.MIN_VALUE can't happen. Think of MONTH, represented as int.
byte abs (byte in) throws ArithmeticException {
if (in == Byte.MIN_VALUE) throw new ArithmeticException ("abs called on Byte.MIN_VALUE");
return (in < 0) ? (byte) -in : in;
}
The "let's ignore the rare cases of MIN_VALUE" habit is not an option. First make the code work - then make it fast. If the user needs a faster, but buggy solution, he should write it himself.
The simplest solution that might work means: simple, but not too simple.
Since the code doesn't rely on state, the method can and should be made static. This allows for a quick test:
public static void main (String args []) {
System.out.println (abs(new Byte ( "7")));
System.out.println (abs(new Byte ("-7")));
System.out.println (abs((byte) 7));
System.out.println (abs((byte) -7));
System.out.println (abs(new Byte ( "127")));
try
{
System.out.println (abs(new Byte ("-128")));
}
catch (ArithmeticException ae)
{
System.out.println ("Integer: " + Math.abs (new Integer ("-128")));
}
System.out.println (abs((byte) 127));
System.out.println (abs((byte) -128));
}
I catch the first exception and let it run into the second, just for demonstration.
There is a bad habit in programming, which is that programmers care much more for fast than for correct code. What a pity!
If you're curious why there is one more negative than positive value, I have a diagram for you.
Although this shouldn't be a bottle neck as branching issues on modern processors isn't normally a problem, but in the case of integers you could go for a branch-less solution as outlined here: http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs.
(x + (x >> 31)) ^ (x >> 31);
This does fail in the obvious case of Integer.MIN_VALUE however, so this is a use at your own risk solution.
In case of the absolute value of an integer x without using Math.abs(), conditions or bit-wise operations, below could be a possible solution in Java.
(int)(((long)x*x - 1)%(double)x + 1);
Because Java treats a%b as a - a/b * b, the sign of the result will be same as "a" no matter what sign of "b" is; (x*x-1)%x will equal abs(x)-1; type casting of "long" is to prevent overflow and double allows dividing by zero.
Again, x = Integer.MIN_VALUE will cause overflow due to subtracting 1.
You can use :
abs_num = (num < 0) ? -num : num;
Here is a one-line solution that will return the absolute value of a number:
abs_number = (num < 0) ? -num : num;
-num will equal to num for Integer.MIN_VALUE as
Integer.MIN_VALUE = Integer.MIN_VALUE * -1
Lets say if N is the number for which you want to calculate the absolute value(+ve number( without sign))
if (N < 0)
{
N = (-1) * N;
}
N will now return the Absolute value
I want to find the zero points of a sine function. The parameter is a interval [a,b]. I have to it similar to binary search.
Implement a function that searches for null points in the sinus function in a interval between a and b. The search-interval[lower limit, upper limit] should be halved until lower limit and upper limit are less then 0.0001 away from each other.
Here is my code:
public class Aufg3 {
public static void main(String[] args) {
System.out.println(zeropoint(5,8));
}
private static double zeropoint(double a, double b){
double middle = (a + b)/2;
if(Math.sin(middle) < 0){
return zeropoint(a,middle);
}else if(Math.sin(middle) > 0){
return zeropoint(middle,b);
}else{
return middle;
}
}
}
It gives me a lot of errors at the line with return zeropoint(middle,b);
In a first step I want to find just the first zero point in the interval.
Any ideas?
Fundamental problems that everybody has overlooked:
we don't always want to return a result (imagine finding the zero points of the sine function between pi/4 and 3pi/4, there aren't any).
in any arbitrary range range there may be several zeros.
Clearly what is needed is a (possibly empty) set of values.
So pseudocode of the function really asked for (not using Java as this is homework):
Set zeropoint(double a, double b)
{
double middle = mid point of a and b;
if a and be less than 0.0001 apart
{
if (sin(a) and sin(b) are on opposite sides of 0)
{
return set containing middle
}
else
{
return empty set
}
}
else
{
return union of zeropoint(a, middle) and zeropoint(middle, b)
}
}
Simply saying "it gives me errors" is not very helpful. What kind of errors? Compile errors or uncaught exceptions at runtime?
For your code, two things stand out as possible problems:
the variable mitte does not appear to be declared anywhere.
you are using > and < to compare reals. While that is ok by itself, it is better to check for 0 using a tolerance instead of relying on < and >, to avoid problems due to floating point precision. For all practical purposes -0.000000000001 is 0.
There might be other problems as well, I just wrote down the ones that jumped out at first glance.
Edit:
Apparently the mitte was due to an error in pasting the code by the OP (and has since been corrected). As other answers have pointed out, the code falls in to infinite recursion. This is because the recursion calls are on the wrong intervals.
One thing to note, the sin function can be monotonically increasing for one choice of a and b, and monotonically decreasing at some other interval. e.g. It is increasing over [0,pi/2] and it is decreasing over [pi/2,3*pi/2]. Thus the recursive calls need to changed according to the original interval the search is being made in. For one interval Math.sin(middle)<0 implies that Math.sin(x)<0 for all x in [a,middle], but for some other interval the opposite is true. This probably why this falls into infinite recursion for the interval that you are trying. I think this works over some other interval where sin is actually decreasing. Try calling your function over [pi/2,3*pi/2].
I'm guessing you are getting stack overflow errors at runtime. The < and > signs are reversed. Also, you should use .0001 and not 0 to compare to.
Edit 1:
Actually, your basic algorithm has issues. What happens if there are more than one zero in the interval? What happens if sin(a) and the sin(mitte) have the same sign? What happens if there are no zeros in the interval?
Edit 2:
Ok, so I did the problem and fundamentally, your solution is problematic; I would try to start over in thinking how to solve it.
The major issue is that there could be multiple zeros in the interval and you are trying to find each of them. Creating a function that returns a type double can only return one solution. So, rather than creating a function to return double, just return void and print out the zeros as you find them.
Another hint: You are supposed to continue searching until a and b are within .0001 of each other. Your final solution will not use .0001 in any other way. (I.e, your check to see if you found a zero should not use the .0001 tolerance and nor will it use 0 exactly. Think about how you will really know if you have found a zero when abs(a-b) is less than .0001.
Did you read the assignment to the end? It says:
The search-interval[lower limit, upper
limit] should be halved until lower
limit and upper limit are less then
0.0001 away from each other.
So you can't expect Math.sin(middle) to return exactly zero because of floating point precision issues. Instead you need to stop the recursion when you reach 0.0001 precision.
My guess is that you're running into a StackOverflowError. This is due to the fact that you're never reaching a base case in your recursion. (Math.sin(middle) may never equal exactly 0!)
Your exercise says
[...] until lower limit and upper limit are less then 0.0001 away from each other.
So, try putting this in top of your method:
double middle = (a + b)/2;
if (b - a < 0.0001)
return middle;
Besides some floating point problems other have mentioned, your algorithm seems to be based on the implicit assumptions that:
sin(a) is positive
sin(b) is negative, and
sin(x) is a decreasing function on the interval [a,b].
I see no basis for these assumptions. When any of them is false I don't expect your algorithm to work. They are all false when a=5 and b=8.
if(Math.sin(mitte) < 0){
Where is mitte declared? Isn't mitte middle?
private static double zeropoint(double a, double b){
double middle = (a + b)/2;
double result = middle;
if (Math.abs(a - b) > 0.0001) {
double sin = Math.sin(middle);
if (Math.abs(sin) < 0.0001) {
result = middle;
} else if (sin > 0) {
result = zeropoint(a, middle);
} else {
result = zeropoint(middle, b);
}
}
return result;
}
something like this i think - just to fix first errors