developer tip

항상 다음 정수로 반올림하는 방법

copycodes 2020. 10. 6. 08:22
반응형

항상 다음 정수로 반올림하는 방법 [중복]


이 질문에 이미 답변이 있습니다.

웹 사이트에서 호출기를 만들 때 총 페이지를 찾으려고합니다 (그래서 결과를 정수로 만들고 싶습니다. 레코드 목록을 얻고 페이지 당 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 원칙 ) :

각 상자에 개체 xy들어갈 경우 개체 를 저장하려면 몇 개의 상자가 필요 합니까?

해결책:

  1. 마지막 상자 부분적으로 비어 있을있다는 인식에서 파생됩니다.
  2. 되고 (x + y - 1) ÷ y하여 정수 나눗셈을 .

당신은 3에서 불러올 것 번째의 것을 학년 수학 정수 나누기는 우리가 말할 때 우리가 무슨 일을하는지입니다 5 ÷ 2 = 2.

부동 소수점 나누기 는 우리가라고 말할 때 5 ÷ 2 = 2.5이지만 여기서는 원하지 않습니다 .

많은 프로그래밍 언어가 정수 나누기를 지원합니다. 당신이 나눌 때 C에서 파생 된 언어에서, 당신은 자동으로 얻을 수 int(유형 short, int, long, 등). 나누기 연산의 나머지 / 분수 부분은 간단히 삭제됩니다.

5 / 2 == 2

원래 질문을 다음으로 대체하면 다음 x = 5y = 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

반응형