항상 다음 정수로 반올림하는 방법 [중복]
이 질문에 이미 답변이 있습니다.
웹 사이트에서 호출기를 만들 때 총 페이지를 찾으려고합니다 (그래서 결과를 정수로 만들고 싶습니다. 레코드 목록을 얻고 페이지 당 10 개로 나누고 싶습니다 (페이지 수)).
내가 이것을 할 때 :
list.Count() / 10
또는
list.Count() / (decimal)10
그리고 list.Count() =12
, 나는 결과를 얻습니다 1
.
2
이 경우 어떻게 코드를 작성합니까 (나머지는 항상 추가해야 함 1
)
Math.Ceiling((double)list.Count() / 10);
(list.Count() + 9) / 10
여기에있는 다른 모든 것은 과잉이거나 단순히 잘못되었습니다 ( 굉장한 bestsss의 답변 제외 ). 우리는 할 수 없습니다 함수 호출 (의 오버 헤드 원하는 Math.Truncate()
, Math.Ceiling()
간단한 수학이 충분히있는 경우 등).
OP의 질문은 다음과 같이 일반화됩니다 ( pigeonhole 원칙 ) :
각 상자에 개체
x
만y
들어갈 경우 개체 를 저장하려면 몇 개의 상자가 필요 합니까?
해결책:
- 마지막 상자 가 부분적으로 비어 있을 수 있다는 인식에서 파생됩니다.
- 되고
(x + y - 1) ÷ y
하여 정수 나눗셈을 .
당신은 3에서 불러올 것 번째의 것을 학년 수학 정수 나누기는 우리가 말할 때 우리가 무슨 일을하는지입니다 5 ÷ 2 = 2
.
부동 소수점 나누기 는 우리가라고 말할 때 5 ÷ 2 = 2.5
이지만 여기서는 원하지 않습니다 .
많은 프로그래밍 언어가 정수 나누기를 지원합니다. 당신이 나눌 때 C에서 파생 된 언어에서, 당신은 자동으로 얻을 수 int
(유형 short
, int
, long
, 등). 나누기 연산의 나머지 / 분수 부분은 간단히 삭제됩니다.
5 / 2 == 2
원래 질문을 다음으로 대체하면 다음 x = 5
과 y = 2
같습니다.
각 상자에 2 개의 개체 만 들어갈 경우 5 개의 개체를 저장하려면 몇 개의 상자가 필요합니까?
이제 답은 분명합니다 3 boxes
.-처음 두 상자에는 각각 두 개의 개체가 있고 마지막 상자에는 하나가 있습니다.
(x + y - 1) ÷ y =
(5 + 2 - 1) ÷ 2 =
6 ÷ 2 =
3
따라서 추가 함수 호출을 사용하지 않는 솔루션을 제공 하는 원래 질문 인 x = list.Count()
, y = 10
은 다음과 같습니다.
(list.Count() + 9) / 10
적절한 벤치 마크 또는 숫자의 거짓말
에 대한 인수를 다음 Math.ceil(value/10d)
과 (value+9)/10
내가 적당한 비 죽은 코드를 코딩 결국, 모드 벤치 마크 비 해석한다. 마이크로 벤치 마크를 작성하는 것은 쉬운 일이 아니라고 말하고 있습니다. 아래 코드는이를 보여줍니다.
00:21:40.109 starting up....
00:21:40.140 doubleCeil: 19444599
00:21:40.140 integerCeil: 19444599
00:21:40.140 warming up...
00:21:44.375 warmup doubleCeil: 194445990000
00:21:44.625 warmup integerCeil: 194445990000
00:22:27.437 exec doubleCeil: 1944459900000, elapsed: 42.806s
00:22:29.796 exec integerCeil: 1944459900000, elapsed: 2.363s
핫스팟이 어떻게 최적화하고 공정한 결과를 보장하는지 잘 알고 있기 때문에 벤치 마크는 Java에 있습니다. 그러한 결과로 통계, 소음 또는 그 어떤 것도 그것을 더럽힐 수 없습니다.
Integer ceil은 훨씬 더 빠릅니다.
코드
package t1;
import java.math.BigDecimal;
import java.util.Random;
public class Div {
static int[] vals;
static long doubleCeil(){
int[] v= vals;
long sum = 0;
for (int i=0;i<v.length;i++){
int value = v[i];
sum+=Math.ceil(value/10d);
}
return sum;
}
static long integerCeil(){
int[] v= vals;
long sum = 0;
for (int i=0;i<v.length;i++){
int value = v[i];
sum+=(value+9)/10;
}
return sum;
}
public static void main(String[] args) {
vals = new int[7000];
Random r= new Random(77);
for (int i = 0; i < vals.length; i++) {
vals[i] = r.nextInt(55555);
}
log("starting up....");
log("doubleCeil: %d", doubleCeil());
log("integerCeil: %d", integerCeil());
log("warming up...");
final int warmupCount = (int) 1e4;
log("warmup doubleCeil: %d", execDoubleCeil(warmupCount));
log("warmup integerCeil: %d", execIntegerCeil(warmupCount));
final int execCount = (int) 1e5;
{
long time = System.nanoTime();
long s = execDoubleCeil(execCount);
long elapsed = System.nanoTime() - time;
log("exec doubleCeil: %d, elapsed: %.3fs", s, BigDecimal.valueOf(elapsed, 9));
}
{
long time = System.nanoTime();
long s = execIntegerCeil(execCount);
long elapsed = System.nanoTime() - time;
log("exec integerCeil: %d, elapsed: %.3fs", s, BigDecimal.valueOf(elapsed, 9));
}
}
static long execDoubleCeil(int count){
long sum = 0;
for(int i=0;i<count;i++){
sum+=doubleCeil();
}
return sum;
}
static long execIntegerCeil(int count){
long sum = 0;
for(int i=0;i<count;i++){
sum+=integerCeil();
}
return sum;
}
static void log(String msg, Object... params){
String s = params.length>0?String.format(msg, params):msg;
System.out.printf("%tH:%<tM:%<tS.%<tL %s%n", new Long(System.currentTimeMillis()), s);
}
}
이것은 또한 작동합니다.
c = (count - 1) / 10 + 1;
Math.Ceiling을 사용할 수 있습니다.
http://msdn.microsoft.com/en-us/library/system.math.ceiling%28v=VS.100%29.aspx
가장 쉬운 방법은 두 개의 정수를 나누고 1 씩 늘리는 것입니다.
int r = list.Count() / 10;
r += (list.Count() % 10 == 0 ? 0 : 1);
라이브러리 나 기능이 필요 없습니다.
올바른 코드로 편집했습니다.
mod를 사용하여 확인하십시오. 나머지가 있으면 값을 1 씩 증가 시키십시오.
Xform이 간단한 천장을 위해 두 배로 (그리고 뒤로)?
list.Count()/10 + (list.Count()%10 >0?1:0)
-이 나쁜, div + mod
edit 1st: on a 2n thought that's probably faster (depends on the optimization): div * mul (mul is faster than div and mod)
int c=list.Count()/10;
if (c*10<list.Count()) c++;
edit2 scarpe all. forgot the most natural (adding 9 ensures rounding up for integers)
(list.Count()+9)/10
참고URL : https://stackoverflow.com/questions/4846493/how-to-always-round-up-to-the-next-integer
'developer tip' 카테고리의 다른 글
C # 코드가 컴파일되지 않습니다. (0) | 2020.10.06 |
---|---|
Firebase 용 Cloud Functions로 업로드 된 파일에서 다운로드 URL 가져 오기 (0) | 2020.10.06 |
Console.WriteLine ()과 Debug.WriteLine ()의 차이점은 무엇입니까? (0) | 2020.10.05 |
조각의 MapView (Honeycomb) (0) | 2020.10.05 |
방향 변경시 Fragment를 처리하는 확실한 방법 (0) | 2020.10.05 |