I'm trying to think of how to use recursion to find complement of a number.
For example each digit x of a number must become 9 - x, so 1234 -> 8765.
I can't really think how to do that. This is my code so far:
public static int complement(int n){
int x = n % 10;
x = x - 9;
n = (n / 10)
return complement(n,x);
}
public static int complement(int n ,int times){
}
When you are dealing with recursion, it is important to write the algoritm first in English (or your native tongue :) ).
For this task, consider the following:
I have an number n. Let's take the last digit and subtract this digit to 9.
Do this again for the rest of the digits, i.e. n / 10. With the result obtained, we need to make a number again: so we multiply the result by 10 and add the digit we calculated before. In other words, complement(n / 10) returns the complement of the number n without the last digit, so we need to append the complement of the last digit to this.
When the number is less than 10, we have nothing more to do and we can just return 9 - n (this is the base case, the number is only one digit long).
In code, this is implemented as:
public static int complement(int n) {
if (n < 10) {
return 9 - n;
}
int x = n % 10;
x = 9 - x;
return 10 * complement(n / 10) + x;
}
and then:
System.out.println(complement(1234)); // prints 8765
This can be written a bit shorter with:
public static int complement(int n) {
if (n < 10) {
return 9 - n;
}
return 10 * complement(n / 10) + 9 - n % 10;
}
Related
I recently came across an interview question which although had an immediately obvious solution, I struggled to find a more efficient one.
The actual question involved counting numbers from a to b (up to 2^64) which satisfied having either the digit 6 or 8, but not both. They called it a 'lucky number'. So for example:
126 - lucky
88 - lucky
856 - not lucky
The obvious thought was to brute force it by testing each number between a and b as a string, to check for the relevant characters. However, this was prohibitively slow as expected.
A much better solution that I tried, involved first computing all the 'lucky numbers' which had the number of digits between the number of digits that a and b have (by counting possible combinations):
long n = 0;
for (int occurrences = 1; occurrences <= maxDigits; occurrences++) {
n += (long) Math.pow(8, digits - occurrences) * choose(digits, occurrences);
}
return 2 * n;
and then using the brute force method to compute the number of extra lucky numbers that I had counted. So for example, if a = 3 and b = 21, I could count the number of 1 and 2 digit lucky numbers, then subtract the count of those in [1, 3) and (21, 99].
However, although this was a massive improvement, the brute force element still slowed it down way too much for most cases.
I feel like there must be something I am missing, as the rest of the interview questions were relatively simple. Does anyone have any idea of a better solution?
Although I have tagged this question in Java, help in any other languages or pseudocode would be equally appreciated.
I would say you are at the right track. The gut feeling is that dealing with the a and b separately is easier. Making a function count_lucky_numbers_below(n) allows
return count_lucky_numbers_below(b) - count_lucky_numbers_below(a);
The combinatorial approach is definitely a way to go (just keep in mind that the sum is actually equal to 9**n - 8**n, and there is no need to compute the binomial coefficients).
The final trick is to recurse down by a numbeer of digits.
Lets say n is an N-digit number, and the most significant digit is 5. Each set of N-digit numbers starting with a smaller digit contributes S = 9**(N-1) - 8**(N-1) to the total; you immediately have 5*S of lucky numbers. To deal with the remainder, you need to compute the lucky numbers for the N-1-digit tail.
Of course, care must be taken if the most significant digit is above 5. You need to special case it being 6 or 8, but it doesn't seem to be too complicated.
In the end the answer from #user58697 pushed me in the right direction towards finding a solution. With my (albeit extremely primitive) benchmark, it handles 1 to 2^63 - 1 in less than 2 nanoseconds, so it is definitely fast enough. However it is still more verbose than I would have liked, especially given that I was originally expected to write it in half an hour, so I feel like there is still an easier solution that gives comparable performance.
long countLuckyNumbersBetween(long a, long b) {
return countLuckyNumbersBelow(b) - countLuckyNumbersBelow(a - 1);
}
long countLuckyNumbersBelow(long n) {
return countNumbers(n, 6, 8) + countNumbers(n, 8, 6);
}
/**
* Counts the natural numbers in [0, {to}] that have {including} as a digit, but not {excluding}.
* {excluding} should be in (0, 9] or -1 to exclude no digit.
*/
long countNumbers(long to, int including, int excluding) {
if (including == -1) return 0;
if (to < 10) {
if (to >= including) {
return 1;
} else {
return 0;
}
}
int nSignificand = significand(to);
int nDigits = countDigits(to);
long nTail = to % (long) Math.pow(10, nDigits - 1);
// The count of numbers in [0, 10^(nDigits-1)) that include and exclude the relevant digits
long bodyCount;
if (excluding == -1) {
bodyCount = (long) (Math.pow(10, nDigits - 1) - Math.pow(9, nDigits - 1));
} else {
bodyCount = (long) (Math.pow(9, nDigits - 1) - Math.pow(8, nDigits - 1));
}
long count = 0;
for (int i = 0; i < nSignificand; i++) {
if (i == including) {
if (excluding == -1) {
count += Math.pow(10, nDigits - 1);
} else {
count += Math.pow(9, nDigits - 1);
}
} else if (i != excluding) {
count += bodyCount;
}
}
if (nSignificand == including) {
count += 1 + nTail - countNumbers(nTail, excluding, -1);
} else if (nSignificand != excluding) {
count += countNumbers(nTail, including, excluding);
}
return count;
}
int significand(long n) {
while (n > 9) n /= 10;
return (int) n;
}
int countDigits(long n) {
if (n <= 1) {
return 1;
} else {
return (int) (Math.log10(n) + 1);
}
}
Here is another approach:
264 = 18446744073709551616
We can represent the number as a sum of components (one component per every digit position):
18446744073709551616 associated range of numbers
———————————————————— ———————————————————————————————————————————
0xxxxxxxxxxxxxxxxxxx => [00000000000000000000;09999999999999999999]
17xxxxxxxxxxxxxxxxxx => [10000000000000000000;17999999999999999999]
183xxxxxxxxxxxxxxxxx => [18000000000000000000;18399999999999999999]
1843xxxxxxxxxxxxxxxx => [18400000000000000000;18439999999999999999]
18445xxxxxxxxxxxxxxx => [18440000000000000000;18445999999999999999]
...
1844674407370955160x => [18446744073709551600;18446744073709551609]
18446744073709551616 => [18446744073709551610;18446744073709551616]
If we could compute the amount of lucky numbers for every component, then the sum of the amounts for every component will be the total amount for 264.
Note that every component consists of a prefix followed by xs.
Imagine that we know how many lucky numbers there are in an n-digit xx..x (i.e. numbers [0..0 - 9..9]), let's call it N(n).
Now let's look at a component 18445x..x. where 18445 is a prefix and an n-digit xx..x.
In this component we look at all numbers from 18440xx..x to 18445xx..x.
For every item 1844dxx..x we look at the prefix 1844d:
if prefix contains no 6 or 8, then it's the same as x..x without prefix => N(n) special numbers
if prefix contains 6 and no 8, then x..x cannot contain 8 => 9ⁿ special numbers
if prefix contains 8 and no 6, then x..x cannot contain 6 => 9ⁿ special numbers
if prefix contains 6 and 8 => 0 special numbers
Now let's compute N(n) — the amount of lucky numbers in an n-digit xx..x (i.e. in [0..0 - 9..9]).
We can do it iteratively:
n=1: there are only 2 possible numbers: 8 and 6 => N(1)=2.
n=2: there are 2 groups:
8 present: 8x and x8 where x is any digit except 6
6 present: 6x and x6 where x is any digit except 8
=> N(2)=4*9=34.
n=3: let's fix the 1st digit:
0xx — 5xx, 7xx, 9xx => 8 * N(2)
6xx: xx are any 2 digits except 8 => 9²
8xx: xx are any 2 digits except 6 => 9²
=> N(3) = 8*N(2) + 2*9².
n=k+1 => N(k+1) = 7*N(k) + 2*9ᵏ
Here is an implementation (not 100% tested):
public final class Numbers {
public long countLuckyNumbersBelow(BigInteger num) {
if (num.compareTo(BigInteger.ZERO) < 0) {
throw new IllegalArgumentException("num < 0: " + num);
}
var numberText = num.toString();
var result = 0L;
for (var digitPosition = 0; digitPosition < numberText.length(); digitPosition++) {
result += countLuckyNumbersForComponent(numberText, digitPosition);
}
return result;
}
private long countLuckyNumbersForComponent(String numberText, int digitPosition) {
var prefixEndIdx = numberText.length() - 1 - digitPosition;
var prefixHas6s = containsChar(numberText, '6', prefixEndIdx);
var prefixHas8s = containsChar(numberText, '8', prefixEndIdx);
if (prefixHas6s && prefixHas8s) {
return 0;
}
var result = 0L;
for (var c = numberText.charAt(prefixEndIdx) - 1; c >= '0'; c--) {
var compNo6s = (!prefixHas6s) && (c != '6');
var compNo8s = (!prefixHas8s) && (c != '8');
if (compNo6s && compNo8s) {
result += countLuckyNumbers(digitPosition);
} else if (compNo6s || compNo8s) {
result += power9(digitPosition);
}
}
return result;
}
private static boolean containsChar(String text, char c, int endIdx) {
var idx = text.indexOf(c);
return (idx > 0) && (idx < endIdx);
}
private long[] countLuckyNumbersCache = {0L, 0L};
/**
* Computes how many lucky numbers are in an n-digit `xx..x`
*/
private long countLuckyNumbers(int numDigits) {
if (countLuckyNumbersCache[0] == numDigits) {
return countLuckyNumbersCache[1];
}
long N;
if (numDigits <= 1) {
N = (numDigits == 1) ? 2 : 0;
} else {
var prevN = countLuckyNumbers(numDigits - 1);
N = (8 * prevN) + (2 * power9(numDigits-1));
}
countLuckyNumbersCache[0] = numDigits;
countLuckyNumbersCache[1] = N;
return N;
}
private long[] power9Cache = {0L, 1L};
/**
* Computes 9<sup>power</sup>
*/
private long power9(int power) {
if (power9Cache[0] == power) {
return power9Cache[1];
}
long res = 1;
var p = power;
if (power > power9Cache[0]) {
p -= power9Cache[0];
res = power9Cache[1];
}
for (; p > 0; p--) {
res *= 9;
}
power9Cache[0] = power;
power9Cache[1] = res;
return res;
}
}
BTW it took me half a day, and I have no idea how is that possible to complete it in 30 minutes.
I guess your interviewers expected from you to demonstrate them your thought process.
Here is the result of my attempt.
First, let me explain a little bit what logic I used.
I used formula S = 9N — 8N (mentioned in the user58697's answer) to compute how many of N-digit numbers are lucky.
How to get this formula:
for N-digit numbers there are 10N numbers in total: N digits, each can take one of 10 values: [0-9].
if we only count numbers without 6, then each digit can only take one of 9 values [0-5,7-9] — it's 9N numbers in total
now we also want only numbers with 8.
We can easily compute how many numbers don't have both 6 and 8: digits in these numbers can only take one of 8 values [0-5,7,9] — it's 8N numbers in total.
As a result, there are S = 9N — 8N numbers which have 8 and no 6.
For numbers with 6 and without 8 the formula is the same.
Also numbers without 6 do not intersect with numbers without 8 — so we can just sum them.
And finally, since we know how to count lucky numbers for intervals [0;10N], we need to split the interval [0; our arbitrary number] into suitable sub-intervals.
For instance, we can split number 9845637 this way:
Sub-interval
Prefix
Digit
N-digit interval
0000000 - 8999999
0 - 8
000000 - 999999
9000000 - 9799999
9
0 - 7
00000 - 99999
9800000 - 9839999
98
0 - 3
0000 - 9999
9840000 - 9844999
984
0 - 4
000 - 999
9845000 - 9845599
9845
0 - 5
00 - 99
9845600 - 9845629
98456
0 - 2
0 - 9
9845630 - 9845637
Now we can compute the number for every sub-interval (just keep attention to digits in prefix — they might contains 8 or 6) and then just sum those numbers to get the final result.
Here is the code:
// Special value for 'requiredDigit': no required digit
private static char NIL = Character.MAX_VALUE;
public static long countLuckyNumbersUpTo(BigInteger number) {
if (number.compareTo(BigInteger.ZERO) < 0) {
throw new IllegalArgumentException("number < 0: " + number);
}
var numberAsDigits = number.toString();
return countNumbersUpTo(numberAsDigits, '6', '8') + countNumbersUpTo(numberAsDigits, '8', '6');
}
// count all numbers in [0;'numberAsDigits'] which have 'requiredDigit' and no 'excludeDigit'
private static long countNumbersUpTo(String numberAsDigits, char requiredDigit, char excludeDigit) {
var highDigit = numberAsDigits.charAt(0);
if (numberAsDigits.length() == 1) {
return (requiredDigit != NIL)
? ((highDigit >= requiredDigit) ? 1 : 0)
: numDigitsInInterval('0', highDigit, excludeDigit);
}
var tailDigits = numberAsDigits.substring(1);
var result = 0L;
// numbers where the highest digit is in [0;`highDigit`)
var numGoodDigits = numDigitsInInterval('0', (char) (highDigit - 1), excludeDigit);
var containsRequiredDigit = (requiredDigit != NIL) && (highDigit > requiredDigit);
if (containsRequiredDigit) {
result += totalNumbers(tailDigits.length(), NIL);
numGoodDigits--;
}
if (numGoodDigits > 0) {
result += numGoodDigits * totalNumbers(tailDigits.length(), requiredDigit);
}
// remaining numbers where the highest digit is `highDigit`
if (highDigit != excludeDigit) {
var newRequiredDigit = (highDigit == requiredDigit) ? NIL : requiredDigit;
result += countNumbersUpTo(tailDigits, newRequiredDigit, excludeDigit);
}
return result;
}
private static int numDigitsInInterval(char firstDigit, char lastDigit, char excludeDigit) {
var totalDigits = lastDigit - firstDigit + 1;
return (excludeDigit <= lastDigit) ? (totalDigits - 1) : totalDigits;
}
// total numbers with given requiredDigit in [0;10^numDigits)
private static long totalNumbers(int numDigits, char requiredDigit) {
return (requiredDigit == NIL) ? pow(9, numDigits) : (pow(9, numDigits) - pow(8, numDigits));
}
private static long pow(int base, int exponent) {
return BigInteger.valueOf(base).pow(exponent).longValueExact();
}
This is my code for the Codewars problem (Java) yet I cannot make it work. I'm pretty sure I've made a stupid mistake somewhere because of my lack of experience (coding for 4 months)
public static int zeros(int n) {
int f = 1;
int zerocount = 0;
for(int i = 2 ; i <= n; i++){
f *= i;
}
String factorial = String.valueOf(f);
String split [] = factorial.split("");
for(int i = 0; i < split.length; i++){
String m = split[i];
if(m.equals( "0")){
zerocount ++;
}
else {
zerocount = 0;
}
}
return zerocount;
}
}
In fact, you do not need to calculate the factorial because it will rapidly explode into a huge number that will overflow even a long. What you want to do is count the number of fives and twos by which each number between 2 and n can be divided.
static int powersoffive(int n) {
int p=0;
while (n % 5 == 0) {
p++;
n /= 5;
}
return p;
}
static int countzeros(int n) {
int fives = 0;
for (int i = 1; i <= n; i++)
fives += powersoffive(i);
return fives;
}
Note: Lajos Arpad's solution is superior.
As pointed out by other users your solution will probably not be accepted because of the exploding factorial you are calculating.
About the code you wrote there are two mistakes you have made:
You are calculating the factorial in the wrong way. You should start with i = 2 in the loop
for(int i = 2; i <= n; i++){
f *= i;
}
Also in Java you cannot compare strings using ==. This is not valid
if(m == "0")
You should compare them like this
if(m.equals("0"))
Anyway this is how I would have resolved the problem
public static int zeros(int n) {
int zerocount = 0;
for (int i = 5; n / i > 0; i *= 5) {
zerocount += n / i;
}
return zerocount;
}
A zero in a base-10 representation of a number is a 2*5. In order to determine the number of trailing zeroes you will need to determine how many times can you divide your number with ten, or, in other words, the minimum of the sum of 2 and 5 factors. Due to the fact that 5 is bigger than 2 and we go sequentially, the number of fives will be the number of trailing zeroes.
A naive approach would be to round down n/5, but that will only give you the number of items divisible with 5. However, for example, 25 is divisible by 5 twice. The same can be said about 50. 125 can be divided by 5 three times, no less.
So, the algorithm would look like this:
int items = 0;
int power = 5;
while (power < n) {
items += (int) (n / power);
power *= 5;
}
Here small numbers are in use in relative terms, but it's only a proof of concept.
You do need to use brute force here and you integers will overflow anyway.
With multiplication trailing zero appears only as the result of 2*5.
Now imagine the factorial represented by a product of it's prime factors.
Notice that for every 5 (five) we will always have 2 (two).
So to calculate the number of zeroes we need to calculate the number of fives.
That can be implemented by continuously dividing N by five and totaling results
In Java code that will be something like this:
static int calculate(int n)
{
int result = 0;
while (n > 0 ) {
n /= 5;
result += n;
}
return result;
}
Problem statement: Three digit sum - Find all the numbers between 1 and 999 where the sum of the 1st digit and the 2nd digit is equal to the 3rd digit.
Examples:
123 : 1+2 = 3
246 : 2+4 = 6
Java:
public class AssignmentFive {
public static void main(String[] args) {
int i=1;
int valuetwo;
int n=1;
int sum = 0;
int valuethree;
int valueone = 0;
String Numbers = "";
for (i = 1; i <= 999; i++) {
n = i;
while (n > 1) {
valueone = n % 10;/*To get the ones place digit*/
n = n / 10;
valuetwo = n % 10;/*To get the tens place digit*/
n = n / 10;
valuethree = n;/*To get the hundreds place digit*/
sum = valuethree + valuetwo;/*adding the hundreds place and
tens place*/
}
/*Checking if the ones place digit is equal to the sum and then print
the values in a string format*/
if (sum == valueone) {
Numbers = Numbers + n + " ";
System.out.println(Numbers);
}
}
}
}
I got my result :
1
10
100
1000
10000
100000
1000000
10000000
100000000
1000000000
10000000001
100000000011
1000000000111
10000000001111
100000000011111
1000000000111111
10000000001111111
100000000011111111
1000000000111111111
Process finished with exit code 0
The result is not showing the actual result like it should be which should show values like: 123, 246 (Please refer to the problem statement above.)
Please let me know what seems to be the issue with the code and how to tweak it.
Don't know what you're trying to do with that while loop, or why you are building up a space-separated string of numbers.
Your code should be something like:
for (int n = 1; n <= 999; n++) {
int digit1 = // for you to write code here
int digit2 = // for you to write code here
int digit3 = // for you to write code here
if (digit1 + digit2 == digit3) {
// print n here
}
}
So basically your question is how to calculate the numbers, right?
My first hint for you would be how to get the first, second and third value from a 2 or 3 digit number.
For example for 3 digits you can do int hundretDigit = (n - (n % 100)) % 100. Of course this is really inefficient. But just get code working before optimizing it ;)
Just think about a way to get the "ten-digit" (2nd number). Then you add them and if they equal the third one you write System.out.println(<number>);
EDIT:
For 2 digit numbers I will give you the code:
if(i >= 10 && i <= 99) {
int leftDigit = (i - (i % 10)) / 10;
if(leftDigit == (i % 10)) {
//Left digit equals right digit (for example 33 => 3 = 3
System.out.println(i);
}
}
Try again and edit your source code. If you have more questions I will edit my (this) answer to give you a little bit more help if you need!
I'm trying to write a program that can multiply all the digits of a number from 0 to 1000 exclusive using only math expressions in Java. My program works fine as long as the user types in a 3-digit number, but results in 0 if they type in anything less than 100.
I have tried getting the last digit of the input with '%10' and removing the last digit with '/10' but without a control statement to detect if the input has been reduced to zero, the program ends up multiplying by 0 when a 2-digit number has been reduced to zero, giving an incorrect result.
public class MultiplyDigits {
public static void main(String[] args){
java.util.Scanner input = new java.util.Scanner(System.in);
System.out.print("Enter a number between 0 and 1000: ");
int number = input.nextInt();
int product = 1;
product*=number%10;
number/=10;
product*=number%10;
number/=10;
product*=number%10;
System.out.println(product);
}
}
An input of 55 should result in 25, but my program does 5 x 5 x 0 = 0
An input of 999 results in 729, which is correct. 9 x 9 x 9 = 729
Some more clarification, this is a problem out of the 2nd chapter of a textbook for complete novices. The author has not covered selection statements, loops, writing our own methods or classes, or anything more advanced than elementary programming, so the implication is that this is doable without those. The book has covered invoking methods in classes built into Java, although the author has only mentioned methods in the Math and System classes. For example, Math.max(), Math.min(), Math.pow(), System.currentTimeMillis();
What about this variant. To find the first number, you can decrease, first of all, the entered number by 100 and add 1 to avoid 0 during multipication. And , as recomended NVioli, the second number should be the same updated to have a possibility to enter number lower then 10. Thus, the final variant is:
int number = input.nextInt();
int t1 = 1 + (number-100) / 100;
int t2 = (1 + (number-10) / 10) % 10; \\By NVioli
int t3 = number % 10;
int product = t1 * t2 * t3;
System.out.println(product);
The first part is to extract the essential code into a separate Java method. I'm calling it dprod, which is short for "digit product".
static int dprod(int x) {
int hun = x / 100 % 10;
int ten = x / 10 % 10;
int one = x / 1 % 10;
return hun * ten * one;
}
The above code is the naive version that only works for numbers >= 100.
To treat numbers less than 100 as expected, you need to replace the hun or ten with 1 if it is 0.
static int dprod(int x) {
int hun = x < 100 ? 1 : x / 100 % 10;
int ten = x < 10 ? 1 : x / 10 % 10;
int one = x / 1 % 10;
return hun * ten * one;
}
The ?: operator is called a conditional operator, therefore it is probably not allowed under your rules. There is a possible workaround by using the ?: operator without writing it explicitly, by using the Math.max function.
static int dprod(int x) {
int hun = Math.max(100, x) / 100 % 10;
int ten = Math.max(10, x) / 10 % 10;
int one = x / 1 % 10;
return hun * ten * one;
}
The Math.max function uses the ?: operator internally, therefore it might be forbidden, too. This is subject to discussion though, since it depends on the exact wording of the rules and their intention.
If Math.max is forbidden, it is possible to implement it entirely without branches or conditions, see this C++ question, which can be translated to Java by replacing int32 with int and by replacing inline with static.
The complete code, including automatic tests, is:
package de.roland_illig.so;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test;
public class DprodTest {
static int dprod(int x) {
int hun = Math.max(x, 100) / 100 % 10;
int ten = Math.max(x, 10) / 10 % 10;
int one = x / 1 % 10;
return hun * ten * one;
}
#Test
public void testDprod() {
assertThat(dprod(999)).isEqualTo(729);
assertThat(dprod(123)).isEqualTo(6);
assertThat(dprod(99)).isEqualTo(81);
assertThat(dprod(9)).isEqualTo(9);
}
}
You could just initialize the program with a length 1000 array, initialize it with the value of each number, and then your real problem simplifies to:
System.out.println(calculatedArray[number]);
Your initialization could even take advantage of the fact that a leading 0 doesn't matter according to your rules (55 and 155 are the same result.)
calculatedArray[55] = calculcate(155);
there are some ways which can help you but all of them has a simple loop or if:
You can use digits = Logarithm of your number(10 base) and then you have number of digits, then you can use a loop to calculate the result. your loop will be repeated digit times so no matter how many digits your number has, it will always work.
You can check if your number is less than 100 and then just add 100 to that, then calculate the result, because of 1 * digit1 * digit2 there will be no error.
Suppose I have Long someLong = 1004L. What efficient method can I use to round this down to 1000L? Note that I do not actually know that someLong == 1004L so I can't simply do someLong -= 4L;. I need a generalizable method. I also want the ability to round down to each 5 instead of each 10, for example a function to round to 1005L (since if we're rounding by 5's then it'll round up instead of down).
More examples .. It could be that I have 1926L and I want to round to 5 meaning I need 1925L. Or I need to round to 10 meaning I need 1930L.
This is very simple.
If you want to round always down:
Your required formula is:
someLong-someLong%10
It is because someLong%10 is the remainder of someLong divided by 10. If you get this from the original number, you get the downrounded value, which you wanted.
The generalization is also simple: you can use 100, or even 13, if you want.
If you want to rounding in another direction (for example, rounding always up or always to the middle), then first to add something to this number, and then round always down.
If you want to round always up:
Then first you need to first add 9, then round always down.
someLong+9-(someLong+9)%10
If you want to round always to the middle:
...also you want to round to the nearest neightbor. Then you first add the half of the required interval, then round always down. For example, for 10 it is:
someLong+5-(someLong+5)%10
If you want to round a value towards the nearest multiple of step using the semantics of BigDecimal.ROUND_HALF_UP (if exactly halfway between two steps, round up), the necessary calculations are:
val += step/2;
val -= val%step;
Try this:
double a=1002l;
double b=a/10;
a=Math.round(b)*10;
System.out.println("Double round of value : "+a);
A generic function to round to the nearest multiple of k would be (works for positives only):
public static long round(long toRound, long k) {
long times = toRound / k;
long reminder = toRound % k;
if (reminder < k / 2) {
return k * times;
} else {
return k * (times + 1);
}
}
And a branchless variant (reminder < k / 2 => (2 * reminder / k) < 1:
public static long round(long toRound, long k) {
long times = toRound / k;
long reminder = toRound % k;
return k * (times + ((2 * reminder) / k));
}
The following example reachs what you need:
public static void main(String[] args) {
Long n = 1004L;
Long n2 = 1005L;
n = round(n);
n2 = round(n2);
System.out.println(n);
System.out.println(n2);
}
private static Long round(Long n) {
if (n%10 <=4) {
return n -=n%10;
} else {
return n += (10-n%10);
}
}
myFloor(long n, int m) {
return n - (n % m);
}
myRound(long n, int m) {
int i = (n % m) >= (m / 2) ? m : 0;
return n + i - (n % m);
}
so m could be 10 , 5 , ...