0

I know one possible way of achieving this:

int a = 7;
int b = -10;

public int makeSmaller(int num) {
  int result = Math.abs(num) - 1;
  if(num > 0) return result;
  else return -result;
}

makeSmaller(a); //returns 6
makeSmaller(b); //returns -9

Are there any more concise way of doing this could use to make this a little cleaner?

EDIT

I want the method to return a result closer to zero by exactly 1, so dividing by 2 or any other number won't work. Neither will multiplying by 0.

AJ Weeks
  • 29
  • 6
  • 2
    You could also multiply it *by* zero. That will make the absolute value closer to zero. – Mysticial Jul 11 '14 at 22:47
  • 1
    AJ Weeks, you should meditate on @Mysticial's comment above and think about the importance of figuring out just what you are trying to accomplish before writing code. – dfeuer Jul 12 '14 at 06:51

4 Answers4

5

Using signum:

public static int makeSmaller(int val) {
    return val-Integer.signum(val);
}
k0rppu
  • 104
  • 2
1

Using Math.abs doesn't gain you anything, since you are testing the sign anyway.

Thus, a more concise formulation:

public int makeSmaller(int num) {
  return num > 0? num-1 : num+1;
}

Since you say you want to make it closer to zero, you should also check the zero case:

public int towardZero(int num) {
  if (num == 0) return 0;
  else return num > 0? num-1 : num+1;
}
Justin Kaeser
  • 5,868
  • 27
  • 46
1
public int makeSmaller(int num) {
  int result = Math.abs(num) - 1;
  if(num > 0) return result;
  else return -result;
}

Why not just this?

public int makeSmaller(int num) {
    return num - (num/Math.abs(num));
}

The parenthetical part will always have the same sign as the number, and will always be 1 (plus or minus).

So, given 7...

7 - (7/|7|) = 7 - 1 = 6

Given -10...

-10 - (-10/|-10|) = - 10 - (-10/10) = -10 - (-1) = -10 + 1 = -9

nhgrif
  • 61,578
  • 25
  • 134
  • 173
0

Not very readable, but working:

    int q = -10;

    final int s[] = new int[]{-1, 1};
    q += s[(q>>>31)];

    System.out.println(q); // print -9

    int q = 10;

    final int s[] = new int[]{-1, 1};
    q += s[(q>>>31)];

    System.out.println(q); // print 9

So you can rewrite your function as:

final static int[] signsInc = new int[]{-1, 1};
public static int makeSmaller(final int num) {
    return (num != 0) ? (num + signsInc[(num>>>31)]) : 0;
}
Iłya Bursov
  • 23,342
  • 4
  • 33
  • 57
  • Why not move the `signsInc` declaration into the method definition? – dfeuer Jul 13 '14 at 00:38
  • @dfeuer there is no sense to create array each time function is called, it is static data and should be outside the method – Iłya Bursov Jul 13 '14 at 02:07
  • Methods can have static variables too. Whether static variables are ever clean is another question, but it makes no difference whether they're declared in a method or in its enclosing class—they're only initialized once in any case. – dfeuer Jul 13 '14 at 03:09
  • @dfeuer are you sure that static variables can be declared inside method in java? – Iłya Bursov Jul 13 '14 at 17:43
  • you're right. I got confused. – dfeuer Jul 15 '14 at 00:08