-6

For instance, I have integers, i.e. 450. I want to get 1/100 of the number N. In this case it should be 4.5, which will rounded to 5.

int i = 450;

int round = Math.round(i/450)?

When the i varies, is this safe always?

marlon
  • 6,029
  • 8
  • 42
  • 76
  • Your example will just give you 1 though? – user2023608 Oct 03 '17 at 03:42
  • 2
    Did you try this code at all? If by "safe" you mean "correct", no, this isn't a good way to write code. Correct the division to `i/100` and it still gives you 4, not 5. What you want is `int round = ( i + 50 ) / 100;` assuming you're not dealing with big enough numbers to get overflow. – Dawood ibn Kareem Oct 03 '17 at 03:42
  • Note that it has to be different for negative numbers. I'll post a proper answer later. – Dawood ibn Kareem Oct 03 '17 at 03:53
  • Just to clarify before I write my answer - do you want the answer for -450 to round up to -4 or down to -5? – Dawood ibn Kareem Oct 03 '17 at 04:05
  • If you want the result to be in a decimal form (i.e 4.5), you need to use float or double. int will always return a whole number. – jwitt98 Oct 03 '17 at 04:07
  • I want an integer. And it's always going to be positive numbers. – marlon Oct 03 '17 at 04:09
  • 1
    Read about rounding modes. Note that there is no "wrong" mode - appropriate method should be chosen for concrete purposes – MBo Oct 03 '17 at 06:39
  • What do you call "safe" ? Usually, numbers don't explode when you round them. –  Oct 03 '17 at 10:35
  • OK, if you're restricting it to positive numbers, then `int round = (i + 50) / 100;` works correctly for all integers between 0 and 2,147,483,597, and is faster than the solutions involving floating point numbers or `BigDecimal`. I see no point in turning this into an answer now, because one respondent has already added it to their answer. You do need extra logic if you want something that also works with negative numbers. – Dawood ibn Kareem Oct 03 '17 at 19:42

3 Answers3

3

i/450 will do an integer division before the result gets passed into Math.round and you won't get what you expected. Even then you got ~1/450 of the value, not 0.01 of it. You need

(int)Math.round(i/100.0);

However you can do rounding with just integer math like either of these

int round = (i + 50)/100; // i + 99 for ceiling
int round = (i - 1)/100 + 1;
int round = i/100 + (i % 100 < 50 ? 0 : 1);

For more information read Rounding integer division (instead of truncating)

See also

These are about ceiling function but you can get the idea

phuclv
  • 37,963
  • 15
  • 156
  • 475
1

For it to work no matter numerator or denominator, then

BigDecimal.valueOf(450).divide(BigDecimal.valueOf(100),RoundingMode.HALF_UP);

Another way could be like

BigDecimal.valueOf(450,2).setScale(0, RoundingMode.HALF_UP);

You can convert back to int using .intValue()

That would only make sense of course when you are dealing with exact decimal math most of the time until the very end, like would be the case for financial applications.

YoYo
  • 9,157
  • 8
  • 57
  • 74
  • 2
    This sounds like overkill. – Henry Oct 03 '17 at 04:44
  • @Henry - the original poster didn’t frame the context very well, but working in a financial system, this is exactly how dollar values are represented. It (precision+scale based types) is also the basis for the decimal system as used in databases. Overkill? Depends. – YoYo Oct 03 '17 at 05:43
  • The other thing is I want to avoid engineering a new original solution that didn’t go through rigid testing. These fringe scenarios are sometimes hard to predict / test. Maximizing core api usage seemed like the safest bet. – YoYo Oct 03 '17 at 05:50
0

I "think" this might be what you are looking for:

float i = 450;

int round = Math.round(i/100);

System.out.println(round);//prints 5

Division with int always rounds down so when i is an int, the expression i/100 returns 4 when i is between 400 and 499.

Alternately, you could cast to float:

int i = 450;

int round = Math.round((float)i/100);

System.out.println(round);//prints 5
jwitt98
  • 1,194
  • 1
  • 16
  • 30
  • as Dawood ibn Kareem said, your second line won't work without casting to `int` – phuclv Oct 03 '17 at 08:16
  • @Lưu Vĩnh Phúc - That's simply not true. Did you try to compile and run it? The reason Dawood ibn Kareem said your line won't work is because you used the overloaded Math.round() method that take a double as a parameter and returns a long. Mine uses a float as a parameter and returns an int. – jwitt98 Oct 03 '17 at 12:17
  • Alternately, this would work also: int round = Math.round(i/100f) – jwitt98 Oct 03 '17 at 12:33