How to test if a double is an integer - java

Is it possible to do this?
double variable;
variable = 5;
/* the below should return true, since 5 is an int.
if variable were to equal 5.7, then it would return false. */
if(variable == int) {
//do stuff
}
I know the code probably doesn't go anything like that, but how does it go?

Or you could use the modulo operator:
(d % 1) == 0

if ((variable == Math.floor(variable)) && !Double.isInfinite(variable)) {
// integer type
}
This checks if the rounded-down value of the double is the same as the double.
Your variable could have an int or double value and Math.floor(variable) always has an int value, so if your variable is equal to Math.floor(variable) then it must have an int value.
This also doesn't work if the value of the variable is infinite or negative infinite hence adding 'as long as the variable isn't inifinite' to the condition.

Guava: DoubleMath.isMathematicalInteger. (Disclosure: I wrote it.) Or, if you aren't already importing Guava, x == Math.rint(x) is the fastest way to do it; rint is measurably faster than floor or ceil.

public static boolean isInt(double d)
{
return d == (int) d;
}

Try this way,
public static boolean isInteger(double number){
return Math.ceil(number) == Math.floor(number);
}
for example:
Math.ceil(12.9) = 13; Math.floor(12.9) = 12;
hence 12.9 is not integer, nevertheless
Math.ceil(12.0) = 12; Math.floor(12.0) =12;
hence 12.0 is integer

Here is a good solution:
if (variable == (int)variable) {
//logic
}

Consider:
Double.isFinite (value) && Double.compare (value, StrictMath.rint (value)) == 0
This sticks to core Java and avoids an equality comparison between floating point values (==) which is consdered bad. The isFinite() is necessary as rint() will pass-through infinity values.

Here's a version for Integer and Double:
private static boolean isInteger(Double variable) {
if ( variable.equals(Math.floor(variable)) &&
!Double.isInfinite(variable) &&
!Double.isNaN(variable) &&
variable <= Integer.MAX_VALUE &&
variable >= Integer.MIN_VALUE) {
return true;
} else {
return false;
}
}
To convert Double to Integer:
Integer intVariable = variable.intValue();

Similar to SkonJeet's answer above, but the performance is better (at least in java):
Double zero = 0d;
zero.longValue() == zero.doubleValue()

My simple solution:
private boolean checkIfInt(double value){
return value - Math.floor(value) == 0;
}

public static boolean isInteger(double d) {
// Note that Double.NaN is not equal to anything, even itself.
return (d == Math.floor(d)) && !Double.isInfinite(d);
}

A simple way for doing this could be
double d = 7.88; //sample example
int x=floor(d); //floor of number
int y=ceil(d); //ceil of number
if(x==y) //both floor and ceil will be same for integer number
cout<<"integer number";
else
cout<<"double number";

My solution would be
double variable=the number;
if(variable-(int)variable=0.0){
// do stuff
}

you could try in this way: get the integer value of the double, subtract this from the original double value, define a rounding range and tests if the absolute number of the new double value(without the integer part) is larger or smaller than your defined range. if it is smaller you can intend it it is an integer value. Example:
public final double testRange = 0.2;
public static boolean doubleIsInteger(double d){
int i = (int)d;
double abs = Math.abs(d-i);
return abs <= testRange;
}
If you assign to d the value 33.15 the method return true. To have better results you can assign lower values to testRange (as 0.0002) at your discretion.

Personally, I prefer the simple modulo operation solution in the accepted answer.
Unfortunately, SonarQube doesn't like equality tests with floating points without setting a round precision. So we have tried to find a more compliant solution. Here it is:
if (new BigDecimal(decimalValue).remainder(new BigDecimal(1)).equals(BigDecimal.ZERO)) {
// no decimal places
} else {
// decimal places
}
Remainder(BigDecimal) returns a BigDecimal whose value is (this % divisor). If this one's equal to zero, we know there is no floating point.

Because of % operator cannot apply to BigDecimal and int (i.e. 1) directly, so I am using the following snippet to check if the BigDecimal is an integer:
value.stripTrailingZeros().scale() <= 0

Similar (and probably inferior) to Eric Tan's answer (which checks scale):
double d = 4096.00000;
BigDecimal bd = BigDecimal.valueOf(d);
String s = bd.stripTrailingZeros().toPlainString();
boolean isInteger = s.indexOf(".")==-1;

Here's a solution:
float var = Your_Value;
if ((var - Math.floor(var)) == 0.0f)
{
// var is an integer, so do stuff
}

Related

Java double incorrect cast to int

When i try cast double to int. My variable "check" is always equals zero. But if i do it in psvm it works. If i do it in class check is always equals zero. How can i fix this problem? I try use Double and Integer for cast it doesn't work too.
I use java 11 on Ubuntu 18.
public class Round {
public int round (double value) {
return (value > 0) ? roundPositiveNubmer(value) : roundNegativeNumber(value);
}
private int roundPositiveNubmer(double value) {
int result;
double checkD = value * 10 % 10;
int check = (int) checkD;
if (check > 5) {
value++;
result = (int) value;
} else {
result = (int) value;
}
return result;
}
private int roundNegativeNumber(double value) {
int result;
double checkD = value * 10 % 10;
int check = (int) checkD;
if (check > -5 && check < 0) {
value--;
result = (int) value;
} else {
result = (int) value;
}
return result;
}
}
When i try to round 23.6. I've got 23 but must 24.
Your code works nicely in the positive case, as JB Nizet already hinted in a comment.
The trouble is with the negative case. round(-23.6) yields -23, not -24. It is caused by this line:
if (check > -5 && check < 0) {
In the -23.6 case check is -6, which is less than -5. I think you want the simpler:
if (check < -5) {
Now -23.6 is rounded to -24. -23.5 is still rounded to -23. If you wanted -24 in this case too:
if (check <= -5) {
You may also want to consider whether you wanted >= in the positive case.
Or just use Math.round()
Sourabh Bhat is right in the comment too: You are reinventing the wheel. Math.round() already does the job that your rounding method is doing. So if you are coding this as an exercise, fine, you’re learning, that’s always good. For production code you should prefer to use the existing built-in library method instead.
int rounded = Math.toIntExact(Math.round(-23.6));
System.out.println("Rounded: " + rounded);
Rounded: -24

Value of null in double should print 0

I have a small doubt that I couldn't get around with that is I have a double variable which stores double value but I want it to print 0 instead of 0.0 when it has no data but whatever I try I couldn't make it work
for example:
double a = 0;
System.out.println(a);
should give me 0 instead of 0.0
I know it's a silly question but can anyone point me in the right direction,
thank you in advance.
Use some method as shown below:
double a = 0.0;
System.out.println(formatA(a));
static String formatA(double a) {
if (a == 0.0)
return "0";
else
return String.valueOf(a);
}
You can cast type of variable 'a' to an integer.
double a = 0;
System.out.println((int)a);
man, double a = 0; is a decimal type. you'd make:
change the type of the value
int a = 0
Or, also you can cast the value.
System.out.println((int) a);
If you don't want to see the fractional part of the double value, you can cast it into long value.
Note, it's not a good idea to cast it into "int" value, because max "double" value is greater than max "int" value.
double a = 0;
System.out.println((long)a);

One liner to check two decimal strings differ only by 1 ulp

I have two decimal numbers in String form that are rounded slightly differently. I want a function that would treat them as "equal" if they only differ by 1 ulp (i.e. only the last digit differs by 1).
Currently the most readable form I can come up with is like:
private static boolean diffByUlp(String oldVal, String newVal) {
BigDecimal nb = new BigDecimal(newVal);
return nb.subtract(new BigDecimal(oldVal)).abs().equals(nb.ulp());
}
However, I'd really like a way to do this in one expression (so it fits in an if statement) and avoid using the expensive BigDecimals.
(BTW: they differ by more than 1 double (binary) ulp.)
Any suggestions?
I assume you are looking for a performance effective solution since you've already mentioned that using BigDecimal is too expensive in your case. Although giving advice on performance without knowing the whole context is quite tricky. You may consider a solution based on comparing characters from both decimal numbers stored as a String. It may give you a quick boost if numbers you compare are usually different starting from very first digits (e.g. comparing 120.0001 with 512.0 can be easily tracked just by comparing first character in both strings). But if for most cases your numbers are pretty close then you might stick to BigDecimal - it's all about measuring the performance with real data.
Below you can find an exemplary solution based on comparing characters from strings. It handles a case where two decimal numbers uses different precision. Also when comparing "1.00" with "1.00001" the first number is "treated" as "1.00000". You can use this class as a utility class that provides you a single static method that you can use in any if statement.
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
final class StringDecimal {
private static final Map<Integer, Integer> charToInt = new ConcurrentHashMap<>();
static {
charToInt.put(48, 0);
charToInt.put(49, 1);
charToInt.put(50, 2);
charToInt.put(51, 3);
charToInt.put(52, 4);
charToInt.put(53, 5);
charToInt.put(54, 6);
charToInt.put(55, 7);
charToInt.put(56, 8);
charToInt.put(57, 9);
}
private static boolean areEqual(String num1, String num2) {
int size = Math.min(num1.length(), num2.length()) - 1;
// 1. Compare first n-1 characters where n is max common length for both strings
for (int i = 0; i < size; i++) {
if (num1.charAt(i) != num2.charAt(i)) {
return false;
}
}
int lastDigitDiff = Math.max(num1.charAt(size), num2.charAt(size)) - Math.min(num1.charAt(size), num2.charAt(size));
// 2. Check last common digit
if (lastDigitDiff > 1) {
return false;
}
// 3. If both decimal numbers have same size, they are equal at this moment
if (num1.length() == num2.length()) {
return true;
}
if (num1.length() > num2.length()) {
return testRemainingDigits(num1, size);
}
return testRemainingDigits(num2, size);
}
private static boolean testRemainingDigits(String num, int size) {
int lastDigitsSum = 0;
int lastDigit = charToInt.getOrDefault((int) num.charAt(num.length() - 1), 0);
// 1. Check if last digit is equal to 1
if (lastDigit > 1) {
return false;
}
// 2. Sum all remaining digits from longer string and accept sum == 1
for (int i = num.length() - 1; i > size; i--) {
lastDigitsSum += charToInt.getOrDefault((int) num.charAt(i), 0);
}
return lastDigit == 0 && lastDigitsSum == 0 ||
lastDigit == 1 && lastDigitsSum == 1;
}
public static void main(String[] args) {
List<List<Object>> numbers = Arrays.asList(
Arrays.asList("1.00", "1.000000", true),
Arrays.asList("120.0", "121.0", false),
Arrays.asList("120.0", "120.1", true),
Arrays.asList("1024.00001", "1024.00000", true),
Arrays.asList("1024.00002", "1024.00000", false),
Arrays.asList("1024.00001", "1024.0000", true),
Arrays.asList("1024.00001", "1024", true),
Arrays.asList("1024.00010", "1024", false),
Arrays.asList("1024.00002", "1024", false),
Arrays.asList("1024.00001", "1025.00001", false)
);
for (List<Object> data : numbers) {
String num1 = (String) data.get(0);
String num2 = (String) data.get(1);
boolean expected = (boolean) data.get(2);
boolean result = areEqual(num1, num2);
String status = expected == result ? "OK" : "FAILED";
System.out.println("["+status+"] " + num1 + " == " + num2 + " ? " + result);
}
}
}
It's very imperative, but it's still quite easy to understand what happens under the hood. Complexity of this algorithm is O(n).
Running this exemplary program produces following output:
[OK] 1.00 == 1.000000 ? true
[OK] 120.0 == 121.0 ? false
[OK] 120.0 == 120.1 ? true
[OK] 1024.00001 == 1024.00000 ? true
[OK] 1024.00002 == 1024.00000 ? false
[OK] 1024.00001 == 1024.0000 ? true
[OK] 1024.00001 == 1024 ? true
[OK] 1024.00010 == 1024 ? false
[OK] 1024.00002 == 1024 ? false
[OK] 1024.00001 == 1025.00001 ? false
I hope it will help you coming up with the best solution to your problem.
You have high expectations in a very "floating" area.
Still one, not so serious, answer:
static boolean probablySame(String x, String y) {
return Math.abs(x.hashCode() - y.hashCode()) <= 1;
}
So you want to compactly check if two decimal values only differ by at most 1. For example 3.2 and 2.4 (difference is 0.8).
First you should note that the only purpose of BigDecimal is to provide infinite space and precision in contrast to the limited datatype double (same holds for BigInteger and int). However you only use it to parse a decimal value from a String. Using that class only for that purpose is quite a big overhead, as you already mentioned. Parsing values can also be done with the Double#parseDouble method (documentation), it returns a compact small double value.
All in all your code could look like this:
private static boolean differAtMostByOne(final String oldVal, final String newVal) {
final double oldValAsDouble = Double.parseDouble(oldVal);
final double newValAsDouble = Double.parseDouble(newVal),
final double difference = Math.abs(oldValAsDouble - newValAsDouble);
final double compareTo = 1.0;
final double precision = 0.000001;
final boolean differByAtMostOne = difference <= compareTo + precision;
return differByAtMostOne;
}
Or the same compact:
private static boolean differAtMostByOne(final String oldVal, final String newVal) {
return Math.abs(Double.parseDouble(oldVal) - Double.parseDouble(newVal)) < 1.000001;
}
Note that a direct comparison with the value 1.0 should be avoided when comparing with decimal values. Instead you should allow a small region around the value to account for precision loss.
Else it could be that you input values whose difference is exactly 1 but the computer may represent it by a value like 1.000000000000000001 and the program should also accept it thus the precision region.
Assuming you need this only for Strings with the same lenght. Following might be a possible solution.
check that the strings are equal, except the last digit
check that the last digit is not more of then by one
The snippet should only demonstrate the principal. Further optimization possible.
static boolean diffByUlp(String s1, String s2) {
for (int i = 0; i < s1.length() - 1; i++) {
if (s1.charAt(i) != s2.charAt(i)) {
return false;
}
}
char c1 = s1.charAt(s1.length() - 1);
char c2 = s2.charAt(s2.length() - 1);
if (c1 >= c2) {
return c1-c2 <= 1;
}
return c2-c1 <= 1;
}

How to determine if a number is positive or negative?

I was asked in an interview, how to determine whether a number is positive or negative. The rules are that we should not use relational operators such as <, and >, built in java functions (like substring, indexOf, charAt, and startsWith), no regex, or API's.
I did some homework on this and the code is given below, but it only works for integer type. But they asked me to write a generic code that works for float, double, and long.
// This might not be better way!!
S.O.P ((( number >> 31 ) & 1) == 1 ? "- ve number " : "+ve number );
any ideas from your side?
The integer cases are easy. The double case is trickier, until you remember about infinities.
Note: If you consider the double constants "part of the api", you can replace them with overflowing expressions like 1E308 * 2.
int sign(int i) {
if (i == 0) return 0;
if (i >> 31 != 0) return -1;
return +1;
}
int sign(long i) {
if (i == 0) return 0;
if (i >> 63 != 0) return -1;
return +1;
}
int sign(double f) {
if (f != f) throw new IllegalArgumentException("NaN");
if (f == 0) return 0;
f *= Double.POSITIVE_INFINITY;
if (f == Double.POSITIVE_INFINITY) return +1;
if (f == Double.NEGATIVE_INFINITY) return -1;
//this should never be reached, but I've been wrong before...
throw new IllegalArgumentException("Unfathomed double");
}
The following is a terrible approach that would get you fired at any job...
It depends on you getting a Stack Overflow Exception [or whatever Java calls it]... And it would only work for positive numbers that don't deviate from 0 like crazy.
Negative numbers are fine, since you would overflow to positive, and then get a stack overflow exception eventually [which would return false, or "yes, it is negative"]
Boolean isPositive<T>(T a)
{
if(a == 0) return true;
else
{
try
{
return isPositive(a-1);
}catch(StackOverflowException e)
{
return false; //It went way down there and eventually went kaboom
}
}
}
This will only works for everything except [0..2]
boolean isPositive = (n % (n - 1)) * n == n;
You can make a better solution like this (works except for [0..1])
boolean isPositive = ((n % (n - 0.5)) * n) / 0.5 == n;
You can get better precision by changing the 0.5 part with something like 2^m (m integer):
boolean isPositive = ((n % (n - 0.03125)) * n) / 0.03125 == n;
You can do something like this:
((long) (num * 1E308 * 1E308) >> 63) == 0 ? "+ve" : "-ve"
The main idea here is that we cast to a long and check the value of the most significant bit. As a double/float between -1 and 0 will round to zero when cast to a long, we multiply by large doubles so that a negative float/double will be less than -1. Two multiplications are required because of the existence of subnormals (it doesn't really need to be that big though).
What about this?
return ((num + "").charAt(0) == '-');
// Returns 0 if positive, nonzero if negative
public long sign(long value) {
return value & 0x8000000000000000L;
}
Call like:
long val1 = ...;
double val2 = ...;
float val3 = ...;
int val4 = ...;
sign((long) valN);
Casting from double / float / integer to long should preserve the sign, if not the actual value...
You say
we should not use conditional operators
But this is a trick requirement, because == is also a conditional operator. There is also one built into ? :, while, and for loops. So nearly everyone has failed to provide an answer meeting all the requirements.
The only way to build a solution without a conditional operator is to use lookup table vs one of a few other people's solutions that can be boiled down to 0/1 or a character, before a conditional is met.
Here are the answers that I think might work vs a lookup table:
Nabb
Steven Schlansker
Dennis Cheung
Gary Rowe
This solution uses modulus. And yes, it also works for 0.5 (tests are below, in the main method).
public class Num {
public static int sign(long x) {
if (x == 0L || x == 1L) return (int) x;
return x == Long.MIN_VALUE || x % (x - 1L) == x ? -1 : 1;
}
public static int sign(double x) {
if (x != x) throw new IllegalArgumentException("NaN");
if (x == 0.d || x == 1.d) return (int) x;
if (x == Double.POSITIVE_INFINITY) return 1;
if (x == Double.NEGATIVE_INFINITY) return -1;
return x % (x - 1.d) == x ? -1 : 1;
}
public static int sign(int x) {
return Num.sign((long)x);
}
public static int sign(float x) {
return Num.sign((double)x);
}
public static void main(String args[]) {
System.out.println(Num.sign(Integer.MAX_VALUE)); // 1
System.out.println(Num.sign(1)); // 1
System.out.println(Num.sign(0)); // 0
System.out.println(Num.sign(-1)); // -1
System.out.println(Num.sign(Integer.MIN_VALUE)); // -1
System.out.println(Num.sign(Long.MAX_VALUE)); // 1
System.out.println(Num.sign(1L)); // 1
System.out.println(Num.sign(0L)); // 0
System.out.println(Num.sign(-1L)); // -1
System.out.println(Num.sign(Long.MIN_VALUE)); // -1
System.out.println(Num.sign(Double.POSITIVE_INFINITY)); // 1
System.out.println(Num.sign(Double.MAX_VALUE)); // 1
System.out.println(Num.sign(0.5d)); // 1
System.out.println(Num.sign(0.d)); // 0
System.out.println(Num.sign(-0.5d)); // -1
System.out.println(Num.sign(Double.MIN_VALUE)); // -1
System.out.println(Num.sign(Double.NEGATIVE_INFINITY)); // -1
System.out.println(Num.sign(Float.POSITIVE_INFINITY)); // 1
System.out.println(Num.sign(Float.MAX_VALUE)); // 1
System.out.println(Num.sign(0.5f)); // 1
System.out.println(Num.sign(0.f)); // 0
System.out.println(Num.sign(-0.5f)); // -1
System.out.println(Num.sign(Float.MIN_VALUE)); // -1
System.out.println(Num.sign(Float.NEGATIVE_INFINITY)); // -1
System.out.println(Num.sign(Float.NaN)); // Throws an exception
}
}
This code covers all cases and types:
public static boolean isNegative(Number number) {
return (Double.doubleToLongBits(number.doubleValue()) & Long.MIN_VALUE) == Long.MIN_VALUE;
}
This method accepts any of the wrapper classes (Integer, Long, Float and Double) and thanks to auto-boxing any of the primitive numeric types (int, long, float and double) and simply checks it the high bit, which in all types is the sign bit, is set.
It returns true when passed any of:
any negative int/Integer
any negative long/Long
any negative float/Float
any negative double/Double
Double.NEGATIVE_INFINITY
Float.NEGATIVE_INFINITY
and false otherwise.
Untested, but illustrating my idea:
boolean IsNegative<T>(T v) {
return (v & ((T)-1));
}
It seems arbitrary to me because I don't know how you would get the number as any type, but what about checking Abs(number) != number? Maybe && number != 0
Integers are trivial; this you already know. The deep problem is how to deal with floating-point values. At that point, you've got to know a bit more about how floating point values actually work.
The key is Double.doubleToLongBits(), which lets you get at the IEEE representation of the number. (The method's really a direct cast under the hood, with a bit of magic for dealing with NaN values.) Once a double has been converted to a long, you can just use 0x8000000000000000L as a mask to select the sign bit; if zero, the value is positive, and if one, it's negative.
If it is a valid answer
boolean IsNegative(char[] v) throws NullPointerException, ArrayIndexOutOfBoundException
{
return v[0]=='-';
}
one more option I could think of
private static boolean isPositive(Object numberObject) {
Long number = Long.valueOf(numberObject.toString());
return Math.sqrt((number * number)) != number;
}
private static boolean isPositive(Object numberObject) {
Long number = Long.valueOf(numberObject.toString());
long signedLeftShifteredNumber = number << 1; // Signed left shift
long unsignedRightShifterNumber = signedLeftShifteredNumber >>> 1; // Unsigned right shift
return unsignedRightShifterNumber == number;
}
This one is roughly based on ItzWarty's answer, but it runs in logn time! Caveat: Only works for integers.
Boolean isPositive(int a)
{
if(a == -1) return false;
if(a == 0) return false;
if(a == 1) return true;
return isPositive(a/2);
}
I think there is a very simple solution:
public boolean isPositive(int|float|double|long i){
return (((i-i)==0)? true : false);
}
tell me if I'm wrong!
Try this without the code: (x-SQRT(x^2))/(2*x)
Write it using the conditional then take a look at the assembly code generated.
Why not get the square root of the number? If its negative - java will throw an error and we will handle it.
try {
d = Math.sqrt(THE_NUMBER);
}
catch ( ArithmeticException e ) {
console.putln("Number is negative.");
}
I don't know how exactly Java coerces numeric values, but the answer is pretty simple, if put in pseudocode (I leave the details to you):
sign(x) := (x == 0) ? 0 : (x/x)
If you are allowed to use "==" as seems to be the case, you can do something like that taking advantage of the fact that an exception will be raised if an array index is out of bounds. The code is for double, but you can cast any numeric type to a double (here the eventual loss of precision would not be important at all).
I have added comments to explain the process (bring the value in ]-2.0; -1.0] union [1.0; 2.0[) and a small test driver as well.
class T {
public static boolean positive(double f)
{
final boolean pos0[] = {true};
final boolean posn[] = {false, true};
if (f == 0.0)
return true;
while (true) {
// If f is in ]-1.0; 1.0[, multiply it by 2 and restart.
try {
if (pos0[(int) f]) {
f *= 2.0;
continue;
}
} catch (Exception e) {
}
// If f is in ]-2.0; -1.0] U [1.0; 2.0[, return the proper answer.
try {
return posn[(int) ((f+1.5)/2)];
} catch (Exception e) {
}
// f is outside ]-2.0; 2.0[, divide by 2 and restart.
f /= 2.0;
}
}
static void check(double f)
{
System.out.println(f + " -> " + positive(f));
}
public static void main(String args[])
{
for (double i = -10.0; i <= 10.0; i++)
check(i);
check(-1e24);
check(-1e-24);
check(1e-24);
check(1e24);
}
The output is:
-10.0 -> false
-9.0 -> false
-8.0 -> false
-7.0 -> false
-6.0 -> false
-5.0 -> false
-4.0 -> false
-3.0 -> false
-2.0 -> false
-1.0 -> false
0.0 -> true
1.0 -> true
2.0 -> true
3.0 -> true
4.0 -> true
5.0 -> true
6.0 -> true
7.0 -> true
8.0 -> true
9.0 -> true
10.0 -> true
-1.0E24 -> false
-1.0E-24 -> false
1.0E-24 -> true
1.0E24 -> true
Well, taking advantage of casting (since we don't care what the actual value is) perhaps the following would work. Bear in mind that the actual implementations do not violate the API rules. I've edited this to make the method names a bit more obvious and in light of #chris' comment about the {-1,+1} problem domain. Essentially, this problem does not appear to solvable without recourse to API methods within Float or Double that reference the native bit structure of the float and double primitives.
As everybody else has said: Stupid interview question. Grr.
public class SignDemo {
public static boolean isNegative(byte x) {
return (( x >> 7 ) & 1) == 1;
}
public static boolean isNegative(short x) {
return (( x >> 15 ) & 1) == 1;
}
public static boolean isNegative(int x) {
return (( x >> 31 ) & 1) == 1;
}
public static boolean isNegative(long x) {
return (( x >> 63 ) & 1) == 1;
}
public static boolean isNegative(float x) {
return isNegative((int)x);
}
public static boolean isNegative(double x) {
return isNegative((long)x);
}
public static void main(String[] args) {
// byte
System.out.printf("Byte %b%n",isNegative((byte)1));
System.out.printf("Byte %b%n",isNegative((byte)-1));
// short
System.out.printf("Short %b%n",isNegative((short)1));
System.out.printf("Short %b%n",isNegative((short)-1));
// int
System.out.printf("Int %b%n",isNegative(1));
System.out.printf("Int %b%n",isNegative(-1));
// long
System.out.printf("Long %b%n",isNegative(1L));
System.out.printf("Long %b%n",isNegative(-1L));
// float
System.out.printf("Float %b%n",isNegative(Float.MAX_VALUE));
System.out.printf("Float %b%n",isNegative(Float.NEGATIVE_INFINITY));
// double
System.out.printf("Double %b%n",isNegative(Double.MAX_VALUE));
System.out.printf("Double %b%n",isNegative(Double.NEGATIVE_INFINITY));
// interesting cases
// This will fail because we can't get to the float bits without an API and
// casting will round to zero
System.out.printf("{-1,1} (fail) %b%n",isNegative(-0.5f));
}
}
This solution uses no conditional operators, but relies on catching two excpetions.
A division error equates to the number originally being "negative". Alternatively, the number will eventually fall off the planet and throw a StackOverFlow exception if it is positive.
public static boolean isPositive( f)
{
int x;
try {
x = 1/((int)f + 1);
return isPositive(x+1);
} catch (StackOverFlow Error e) {
return true;
} catch (Zero Division Error e) {
return false;
}
}
What about the following?
T sign(T x) {
if(x==0) return 0;
return x/Math.abs(x);
}
Should work for every type T...
Alternatively, one can define abs(x) as Math.sqrt(x*x),
and if that is also cheating, implement your own square root function...
if (((Double)calcYourDouble()).toString().contains("-"))
doThis();
else doThat();
Combined generics with double API. Guess it's a bit of cheating, but at least we need to write only one method:
static <T extends Number> boolean isNegative(T number)
{
return ((number.doubleValue() * Double.POSITIVE_INFINITY) == Double.NEGATIVE_INFINITY);
}
Two simple solutions. Works also for infinities and numbers -1 <= r <= 1
Will return "positive" for NaNs.
String positiveOrNegative(double number){
return (((int)(number/0.0))>>31 == 0)? "positive" : "negative";
}
String positiveOrNegative(double number){
return (number==0 || ((int)(number-1.0))>>31==0)? "positive" : "negative";
}
There is a function is the math library called signnum.
http://www.tutorialspoint.com/java/lang/math_signum_float.htm
http://www.tutorialspoint.com/java/lang/math_signum_double.htm
It's easy to do this like
private static boolean isNeg(T l) {
return (Math.abs(l-1)>Math.abs(l));
}
static boolean isNegative(double v) {
return new Double(v).toString().startsWith("-");
}

Are there any functions for truncating a double in java?

Is there a Java Library function which can be used to truncate a number to an arbitrary number of decimal places?
For Example.
SomeLibrary.truncate(1.575, 2) = 1.57
Thanks
Try setScale of BigDecimal like so:
public static double round(double d, int decimalPlace) {
BigDecimal bd = new BigDecimal(d);
bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
return bd.doubleValue();
}
Incredible no one brought this up yet, Java API has had DecimalFormat for ages now for this exact purpose.
For most numbers, you won't be able to get an exact representation of xxx.yyyy unless you use a decimal class with guaranteed accuracy, such as BigDecimal.
There's one in commons-math. Check out http://commons.apache.org/math/apidocs/org/apache/commons/math/util/MathUtils.html:
public static double round(double x,
int scale)
It's implemented using BigDecimal, and is overloaded to allow specifying a rounding method, so you can use it to truncate, like this:
org.apache.commons.math.util.MathUtils.round(1.575, 2,
java.math.BigDecimal.ROUND_DOWN);
Update:
In the last version (Math3), this method is in the class Precision.
org.apache.commons.math3.util.Precision.round(double x, int scale, int roundingMethod)
Simply remove the fractional portion
public double trunk(double value){
return value - value % 1;
}
Use this simple function
double truncateDouble(double number, int numDigits) {
double result = number;
String arg = "" + number;
int idx = arg.indexOf('.');
if (idx!=-1) {
if (arg.length() > idx+numDigits) {
arg = arg.substring(0,idx+numDigits+1);
result = Double.parseDouble(arg);
}
}
return result ;
}
I just want to add to ubuntudroid's solution.
I tried it and it wouldn't round down, so I had to add
df.setRoundingMode(RoundingMode.FLOOR);
for it to work.
here is a short implementation which is many times faster than using BigDecimal or Math.pow
private static long TENS[] = new long[19];
static {
TENS[0] = 1;
for (int i = 1; i < TENS.length; i++) TENS[i] = 10 * TENS[i - 1];
}
public static double round(double v, int precision) {
assert precision >= 0 && precision < TENS.length;
double unscaled = v * TENS[precision];
if(unscaled < Long.MIN_VALUE || unscaled > Long.MAX_VALUE)
return v;
long unscaledLong = (long) (unscaled + (v < 0 ? -0.5 : 0.5));
return (double) unscaledLong / TENS[precision];
}
Delete the assert'ions to taste. ;)
Actually, this sort of thing is easy to write:
public static double truncate(double value, int places) {
double multiplier = Math.pow(10, places);
return Math.floor(multiplier * value) / multiplier;
}
Note that it's Math.floor, because Math.round wouldn't be truncating.
Oh, and this returns a double, because that's what most functions in the Math class return (like Math.pow and Math.floor).
Caveat: Doubles suck for accuracy. One of the BigDecimal solutions should be considered first.
To do it 100% reliably, you'd have to pass the argument as string, not as floating-point number. When given as string, the code is easy to write. The reason for this is that
double x = 1.1;
does not mean that x will actually evaluate to 1.1, only to the closest exactly representable number.
created a method to do it.
public double roundDouble(double d, int places) {
return Math.round(d * Math.pow(10, (double) places)) / Math.pow(10, (double)places);
}

Categories

Resources