Safest way to initialize double variable in java - java

I used to initialize double variables with Double.NaN and fill them later depending on the input. If there were mistakes in inputs I just return Double.NaN. This practice backfired, when other part of application used my function as input and worked just OK, doing basic arithmetic and comparing NaNs with double (but didn't supposed to, I would expect exception).
The obvious solution would be to add Double.isNaN() at the end of my code and throw exception inside my function
But this is a highly used function in highly optimized code, so I'm unwilling to add extra check each time it is called. I would rather prefer break the whole application on wrong parameters once a year than add an extra check, esp. I heard that comparing to NaN takes longer than comparing to double. How do I achieve that and what are best practices in this situation?
EDIT
for example, I want to return first parameter for parametric function which I know nothing about depending on user input
private double getFirstFactor(HashMap <String, Double> userParams) {
double res = Double.NaN;
if(userParams.containsKey("factor1")) {
res = userParams.get("factor1");
}
return res;
}
Usage
double f1 = getFirstFactor(userParams);
double threshold = f(f1); // for example f1 * 100 + f1;
// ideally, code above breaks if f1 is not defined and I don't go futher
if(threshold >= 0) {
...
} else {
...
}

Don't do that.
NaN is used for the result of certain expressions (e.g. 0.0 / 0.0) and has the unique property that it compares false with itself.
You should always initialise double values with something sensible. Depending on your algorithm, 0.0 and 1.0 are often good values.
If you really can't do that then you could always use a Double, with null as your default-initialised value.

You should always validate your inputs before using them. If your inputs are invalid, you can throw an IllegalArgumentException before any computation is done at all. It makes it the caller's responsibility to use your code with correct inputs.
It's always better to fail fast, instead propagating invalid values throughout your system. This can cause big problems (as you probably have experienced).

Use boxed type Double and use null as default value insteed of Double.NaN. If I would need to stick to primitives, I would got for 0.0d as default value.

Related

Creating a class that accepts either a double or string in Java

I am trying to program (in Java) what seems like a relatively easy set of requirements but I am having trouble with types. I want to take scientific data from an instrument and put it through some logic to come up with an answer. My problem is that the data will either come off as a string (always "None") or a double. The data set will be two points per sample. So, here are my thoughts: I need class with two parameters that can be either a string or double. So, I decided I would make a class with generic parameters. When it came to performing the logic on the double or string, I had trouble. For example, here are two parts of the logic:
If v < 26 and f is between 36.5 and 37, then sample needs to be rerun.
If v > 31 and f is "None", then rerun.
There are more rules but I won't include them all here, but both v and f may be either a double or "None".
If all the values were doubles I would have no problem, but the fact that I can get doubles or strings is giving me trouble when trying to compare the two. I'm not sure if a generic class is the way to go. Any ideas?
Also, this is my first post so please let me know if you need more information or have any tips on posting.
Thanks!
You are mistaken: Your input type is always String (if it can be "None" it is a String). However, it can be a String with numbers and a dot that may be parsed as a Double.
Something like this should help:
public static Double parseInput(String input) {
try {
return input.equals("None") ? null : Double.valueOf(input);
} catch (NumberFormatException | NullPointerException e) {
return Double.NaN;
}
}
This returns a null for "None", which seems the most reasonable mapping, and handles anything not a number (blank, null, bad data) by returning the special "not a number" Double value.
I suggest you to use String as parameter type, then inside your class you can try to parse the value to double and apply your logic on it if the value can be parsed to double.
If not, then the value is a String and you have to apply the logic of String values
If all the values were doubles I would have no problem,
Similar to #Bohemian's answer but I would make use of NaN and leave the value a primitive.
public static double parseInput(String input) {
return "None".equalsIgnoreCase(input)
? Double.NaN
: Double.parseDouble(input);
}
To check for none use
If v > 31 and f is "None", then rerun.
if (v > 31 && Double.isNaN(f))

Parse String to Double.NaN

i want to let users edit a field with double data. I want to allow Double.NaN (to void values). Is there a generic way (a predefined string) that is parsed to Double.NaN from the method Double.valueOf(String) without checking it in the background?
There is a special char looking like a diamond with a question mark in it (in HTML) that acts like NaN, but - well - the users wont find that on their keys.
You can pass +NaN or -NaN or NaN to valueOf() and have it return a NaN. The documentation gives the full details.
parseDouble("NaN") will return a NaN value:
System.out.println(Double.isNaN(Double.parseDouble("NaN"));

Java typecasting for retrieving integer part of a double as double

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.

Determining input for Overloaded Method

I'm running into a bit of an issue with determining if the user input is an int or double.
Here's a sample:
public static int Square(int x)
{
return x*x;
}
public static double Square(double x)
{
return x*x;
}
I need to figure out how to determine based on the Scanner if the input is a int or double for the above methods. However since this is my first programming class, I'm not allowed to use anything that hasn't been taught - which in this case, has been the basics.
Is there anyway of possibly taking the input as a String and checking to see if there is a '.' involved and then storing that into an int or double?
Lastly, I'm not asking for you to program it out, but rather help me think of a way of getting a solution. Any help is appreciated :)
The Scanner has a bunch of methods like hasNextInt, hasNextDouble, etc. which tell you whether the "next token read by the Scanner can be interpreted as a (whatever)".
Since you mentioned you've learned about the Scanner object, I assume the methods of that class are available to you for your use. In this case, you can detect if an input is an integer, double, or just obtain an entire line. The methods you would most be interested here would be the hasNextDouble() method (returns a boolean indicating whether or not the current token in the Scanner is actually a double or not) and the nextDouble() method (if the next token in the Scanner is in fact a double, parse it from the Scanner as one). This is probably the best direction for determining input types from a file or standard input.
Another option is to use the wrapper classes static methods for converting values. These are generally named like Integer.parseInt(str) or Double.parseDouble(str) which will convert a given String object into the appropriate basic type. See the Double classes method pasrseDouble(String s) for more details. It could be used in this way:
String value = "123.45"
double convertedValue = 0.0;
try {
convertedValue = Double.parseDouble(value);
} catch (NuberFormatException nfe) {
System.err.println("Not a double");
}
This method is probably best used for values that exist within the application already and need to be verified (it would be overkill to construct a Scanner on one small String for this purpose).
Finally, yet another potential (but not very clean, straightforward, or probably correct technique) could be looking at the String object directly and trying to find if it contains a decimal point, or other indicators that it is in fact a double. You may be able to use indexOf(String substr) to determine if it appears in the String ever. I suspect this method has a lot of potential problems though (say for example, what if the String has multiple '.' characters?). I wouldn't suggest this route because it is error prone and hard to follow. It might be an option if that's what the constraints are, however.
So, IMHO, your options should go as follow:
Use the Scanner methods hasNextDouble() and nextDouble()
Use the wrapper class methods Double.parseDouble(String s)
Use String methods to try and identify the value (avoid this technique at all costs if either of the above options are available).
Since you think you won't be allowed to use the Scanner methods there are a number of alternatives you try. You mentioned checking to see if a String contains a .. To do this you could use the contains method on String.
"Some words".contains("or") // evaluates to true
The problem with this approach is that there are many Strings that contain . but aren't floating point numbers. For examples, sentences, URLs and IP addresses. However, I doubt you're lecturer is trying to catch you out with and will probably just be giving you ints and doubles.
So instead you could try casting. Casting a double to an int results in the decimal portion of the number being discarded.
double doubleValue = 2.7;
int castedDoubleValue = (int) doubleValue; // evaluates to 2
double integerValue = 3.0;
int castedIntegerValue = (int) integerValue; // evaluates to 3
Hopefully, that should be enough to get you started on writing a solution to the problem.
Can be checked like this
if(scanner.hasNextDouble()}
{
System.out.println("Is double");
}
if(scanner.hasNextDouble()}
{
System.out.println("Is double");
}

How to present the nullable primitive type int in Java?

I am designing an entity class which has a field named "documentYear", which might have unsigned integer values such as 1999, 2006, etc. Meanwhile, this field might also be "unknown", that is, not sure which year the document is created.
Therefore, a nullable int type as in C# will be well suited. However, Java does not have a nullable feature as C# has.
I have two options but I don't like them both:
Use java.lang.Integer instead of the primitive type int;
Use -1 to present the "unknown" value
Does anyone have better options or ideas?
Update: My entity class will have tens of thousands of instances; therefore the overhead of java.lang.Integer might be too heavy for overall performance of the system.
Using the Integer class here is probably what you want to do. The overhead associated with the object is most likely (though not necessarily) trivial to your applications overall responsiveness and performance.
You're going to have to either ditch the primitive type or use some arbitrary int value as your "invalid year".
A negative value is actually a good choice since there is little chance of having a valid year that would cause an integer overflow and there is no valid negative year.
Tens of thousands of instances of Integer is not a lot. Consider expending a few hundred kilobytes rather than optimise prematurely. It's a small price to pay for correctness.
Beware of using sentinel values like null or 0. This basically amounts to lying, since 0 is not a year, and null is not an integer. A common source of bugs, especially if you at some point are not the only maintainer of the software.
Consider using a type-safe null like Option, sometimes known as Maybe. Popular in languages like Scala and Haskell, this is like a container that has one or zero elements. Your field would have the type Option<Integer>, which advertises the optional nature of your year field to the type system and forces other code to deal with possibly missing years.
Here's a library that includes the Option type.
Here's how you would call your code if you were using it:
partyLikeIts.setDocumentYear(Option.some(1999));
Option<Integer> y = doc.getDocumentYear();
if (y.isSome())
// This doc has a year
else
// This doc has no year
for (Integer year: y) {
// This code only executed if the document has a year.
}
Another option is to have an associated boolean flag that indicates whether or not your year value is valid. This flag being false would mean the year is "unknown." This means you have to check one primitive (boolean) to know if you have a value, and if you do, check another primitive (integer).
Sentinel values often result in fragile code, so it's worth making the effort to avoid the sentinel value unless you are very sure that it will never be a use case.
You can use a regular int, but use a value such as Integer.MAX_VALUE or Integer.MIN_VALUE which are defined constants as your invalid date. It is also more obvious that -1 or a low negative value that it is invalid, it will certainly not look like a 4 digit date that we are used to seeing.
If you have an integer and are concerned that an arbitrary value for null might be confused with a real value, you could use long instead. It is more efficient than using an Integer and Long.MIN_VALUE is no where near any valid int value.
For completeness, another option (definitely not the most efficient), is to use a wrapper class Year.
class Year {
public int year;
public Year(int year) { this.year = year; }
}
Year documentYear = null;
documentYear = new Year(2013);
Or, if it is more semantic, or you want multiple types of nullable ints (Other than Years), you can imitate C# Nullable primitives like so:
class Int {
public int value;
public Int(int value) { this.value = value; }
#Override
public String toString() { return value; }
}
Using the int primitive vs the Integer type is a perfect example of premature optimization.
If you do the math:
int = N(4)
Integer = N(16)
So for 10,000 ints it'll cost 40,000 bytes or 40k. For 10,000 ints it'll cost 160,000 bytes or 160K. If you consider the amount of memory required to process images/photos/video data that's practically negligible.
My suggestion is, quit wasting time prematurely optimizing based on variable types and look for a good data structure that'll make it easy to process all that data. Regardless of that you do, unless you define 10K primitive variables individually, it's going to end up on the heap anyway.
What's wrong with java.lang.Integer? It's a reasonable solution, unless you're storing very large amounts of this value maybe.
If you wanted to use primitives, a -1 value would be a good solution as well. The only other option you have is using a separate boolean flag, like someone already suggested. Choose your poison :)
PS: damn you, I was trying to get away with a little white lie on the objects vs structs. My point was that it uses more memory, similar to the boolean flag method, although syntactically the nullable type is is nicer of course. Also, I wasn't sure someone with a Java background would know what I meant with a struct.
java.lang.Integer is reasonable for this case. And it already implemented Serializable, so you can save just only the year field down to the HDD and load it back.
Another option might be to use a special value internally (-1 or Integer.MIN_VALUE or similar), but expose the integer as two methods:
hasValue() {
return (internalValue != -1);
}
getValue() {
if (internalValue == -1) {
throw new IllegalStateException(
"Check hasValue() before calling getValue().");
}
return internalValue;
}
If you're going to save memory, I would suggest packing several years in a single int. Thus 0 is nil. Then you can make assumptions in order to optimize. If you are working only with the current dates, like years 1970—2014, you can subtract 1969 from all of them and get into 1—55 range. Such values can be coded with only 6 bits. So you can divide your int which is always 32 bit, into 4 zones, with a year in there. This way you can pack 4 years in the range 1970—2226 into a single int. The more narrow your range is, like only 2000—2014 (4 bits), the more years you can pack in a single int.
You could use the #Nullable annotation if using java 7

Categories

Resources