C ++:数値の最も近い倍数に切り上げる


168

OK-これは基本的な質問のように思われるため、ここに投稿するのはほとんど恥ずかしいです(そして、誰かが投票に投票した場合は削除します)。

これはC ++で数値の倍数に切り上げる正しい方法ですか?

私はこれに関連する他の質問があることを知っていますが、C ++でこれを行うための最良の方法は何かを知ることに特に興味があります。

int roundUp(int numToRound, int multiple)
{
 if(multiple == 0)
 {
  return numToRound;
 }

 int roundDown = ( (int) (numToRound) / multiple) * multiple;
 int roundUp = roundDown + multiple; 
 int roundCalc = roundUp;
 return (roundCalc);
}

更新:申し訳ありませんが、私はおそらく意図を明確にしませんでした。ここではいくつかの例を示します。

roundUp(7, 100)
//return 100

roundUp(117, 100)
//return 200

roundUp(477, 100)
//return 500

roundUp(1077, 100)
//return 1100

roundUp(52, 20)
//return 60

roundUp(74, 30)
//return 90

3
ロジックにエラーがあります。たとえば、4を最も近い2の倍数に切り上げたいとします。roundDown=(4/2)* 2 = 4; 切り上げ= 4 + 2; そのため、roundCalc = 6です。その場合は4を返したいと思います。
Niki Yoshiuchi、2010

これは、roundUp(30,30)では機能しません。それが答えとして60を与え、それはまだ答えとして30を与える必要があります...
bsobaid

@bsobaid:下部にある私の答えを確認してください。ここでも他のソリューションよりも少し単純ですが、それらも機能するはずです
Niklas B.

3
テストケースは、負の数を含む例が著しく不足している場合、除算が正確な場合、除算がほぼ正確な場合、および数値がの範囲の限界に非常に近い場合ですint

1
Robben_Ford_Fan_boy、あなたが行った答えのある編集は削除されるべきです。与えられた回答と異なる場合は、独自の回答を投稿できます。現状では、この回答には問題があり、回答セクションで対処する必要があります。
chux-モニカを

回答:


161

これは正の数で機能しますが、負の数ではわかりません。整数演算のみを使用します。

int roundUp(int numToRound, int multiple)
{
    if (multiple == 0)
        return numToRound;

    int remainder = numToRound % multiple;
    if (remainder == 0)
        return numToRound;

    return numToRound + multiple - remainder;
}

編集:これは負の数で機能するバージョンです。「アップ」とは、常に入力>>である結果を意味します。

int roundUp(int numToRound, int multiple)
{
    if (multiple == 0)
        return numToRound;

    int remainder = abs(numToRound) % multiple;
    if (remainder == 0)
        return numToRound;

    if (numToRound < 0)
        return -(abs(numToRound) - remainder);
    else
        return numToRound + multiple - remainder;
}

+1私の意見では、間違いなく最も素晴らしく、最も読みやすいソリューションです。
Robben_Ford_Fan_boy 2010

1
if(number<0){ multiple = multiple*(-1); }負の数を正しい方向に丸めるために最初に追加します
Josh

4
@ジョシュ:なぜ乗算を使うの?if(number<0) multiple = -multiple簡単です。
md5 2013年

これは、roundUp(30,30)では機能しません。答えは60ですが、答えは30です。
bsobaid 2014年

@bsobaid不可能。if (remainder == 0)テストでは、そのような場合の世話をする必要があります。それは私のために働きます:ideone.com/Waol7B
マークランサム

114

条件なし:

int roundUp(int numToRound, int multiple) 
{
    assert(multiple);
    return ((numToRound + multiple - 1) / multiple) * multiple;
}

これは、負の数に対してゼロから四捨五入するように機能します

編集:負の数でも機能するバージョン

int roundUp(int numToRound, int multiple) 
{
    assert(multiple);
    int isPositive = (int)(numToRound >= 0);
    return ((numToRound + isPositive * (multiple - 1)) / multiple) * multiple;
}

テスト


multiple2の累乗の場合(約3.7倍高速http://quick-bench.com/sgPEZV9AUDqtx2uujRSa3-eTE80

int roundUp(int numToRound, int multiple) 
{
    assert(multiple && ((multiple & (multiple - 1)) == 0));
    return (numToRound + multiple - 1) & -multiple;
}

テスト


24
2バージョンの累乗の+1。乗算、除算、またはモジュロのコストを完全に回避できるため、非常に便利です。
ニコスC.

これらのアルゴリズムに前提条件がないことを確信していますか?負の数はどうですか?C ++ 11以前では、動作は未定義のようです。
cubuspl42 2015

>負の数はどうですか?説明したように、これはゼロから四捨五入するような負の数に対して機能します。
KindDragon

「切り上げ」とは、ゼロから四捨五入するのではなく、正の無限大に向かって丸めることを意味します。

8
これ& ~(x - 1)は、& -x2の補数演算と同じです。
トッドリーマン

39

これは、因数が常に正の場合に機能します。

int round_up(int num, int factor)
{
    return num + factor - 1 - (num - 1) % factor;
}

編集:これはを返しますround_up(0,100)=100。を返すソリューションについては、以下のPaulのコメントを参照してくださいround_up(0,100)=0


1
「すでに複数」のケースを処理する最短のケースのようです。
harningt 2012

1
コストのかかる操作の数の点で最適なソリューション。これは、単一のdivisonなし乗算使用しています
ニクラスB.

3
round_up(0、100)== 100承認された回答のように0ではなく
Gregory

7
そうじゃないのnum + factor - 1 - (num + factor - 1) % factor
Paul

6
num - 1 - (num - 1) % factor + factor整数オーバーフローのリスクなしに同じ計算を行います。

24

これは、「nビットのバイト数を調べるにはどうすればよいですか(A:(nビット+ 7)/ 8)」の問題を一般化したものです。

int RoundUp(int n, int roundTo)
{
    // fails on negative?  What does that mean?
    if (roundTo == 0) return 0;
    return ((n + roundTo - 1) / roundTo) * roundTo; // edit - fixed error
}

1
これは、数値の次の倍数に切り上げません。
aaaa bbbb

7
私がこのソリューションを気に入っているのは、roundToが2の累乗になる場合、/と*を削除して、安価な演算(x = roundTo-1; return(n + x)&
〜x

@Trejkazいいえ。それは(x = roundTo - 1; return (n+x)&~roundTo;)私の答えのようになるはずです
KindDragon 2017年

@KindDragonは間違った結果を生成しますが、〜roundToではなく〜xと言うように修正すると、期待した結果が得られます。とにかくJava 8で。
Trejkaz 2017年

@KindDragon:ANDマスクは0xFFF...000、ない、0xFFF7FFFまたは何かである必要があるため、2の-累乗で2 の補数の否定(:マイナス)か、2の累乗より小さい1でビットフリップ(1の補数の逆、~:チルド)が必要ですマイナスではありません)。だから(n+x) & ~xまたは(n-roundTo+1) & -roundTo
Peter Cordes

14
int roundUp(int numToRound, int multiple)
{
 if(multiple == 0)
 {
  return 0;
 }
 return ((numToRound - 1) / multiple + 1) * multiple;  
}

条件をいじる必要はありません


11

短くて甘い答えを探している人のために。これは私が使用したものです。ネガを考慮しない。

n - (n % r)

それは前の要素を返します。

(n + r) - (n % r)

次を返します。これが誰かを助けることを願っています。:)


9
float roundUp(float number, float fixedBase) {
    if (fixedBase != 0 && number != 0) {
        float sign = number > 0 ? 1 : -1;
        number *= sign;
        number /= fixedBase;
        int fixedPoint = (int) ceil(number);
        number = fixedPoint * fixedBase;
        number *= sign;
    }
    return number;
}

これは、任意の浮動小数点数またはベースで機能します(たとえば、-4を最も近い6.75に丸めることができます)。本質的には、固定小数点に変換し、そこで丸めた後、元に戻します。これは、AWAYを0から四捨五入することで負数を処理します。また、基本的に関数をroundDownに変換することで、負の丸め値を処理します。

int固有のバージョンは次のようになります。

int roundUp(int number, int fixedBase) {
    if (fixedBase != 0 && number != 0) {
        int sign = number > 0 ? 1 : -1;
        int baseSign = fixedBase > 0 ? 1 : 0;
        number *= sign;
        int fixedPoint = (number + baseSign * (fixedBase - 1)) / fixedBase;
        number = fixedPoint * fixedBase;
        number *= sign;
    }
    return number;
}

これは多かれ少なかれ台座の答えであり、負の入力サポートが追加されています。


私はfloat roundUpコードをdoubleでテストしましたが、うまくいきました。本当に私の問題を解決します。
Ashif 2014

1
何についてのdouble round(double value, double multiple) { double sign = value; multiple = std::copysign(multiple, 1.0); value = std::copysign(value, 1.0); return std::copysign(multiple * std::ceil(value / multiple), sign); }丸め取得するためのラウンドのためまたはスワップはceil。
Troyseph

8

これは、float、double、long、int、shortで機能するテンプレート関数を使用する最新のc ++アプローチです(ただし、使用されているdouble値のため、long long、long doubleでは機能しません)。

#include <cmath>
#include <iostream>

template<typename T>
T roundMultiple( T value, T multiple )
{
    if (multiple == 0) return value;
    return static_cast<T>(std::round(static_cast<double>(value)/static_cast<double>(multiple))*static_cast<double>(multiple));
}

int main()
{
    std::cout << roundMultiple(39298.0, 100.0) << std::endl;
    std::cout << roundMultiple(20930.0f, 1000.0f) << std::endl;
    std::cout << roundMultiple(287399, 10) << std::endl;
}

しかし、あなたは簡単にするためのサポートを追加することができますlong longし、long double以下のようにテンプレートの特殊化と:

template<>
long double roundMultiple<long double>( long double value, long double multiple)
{
    if (multiple == 0.0l) return value;
    return std::round(value/multiple)*multiple;
}

template<>
long long roundMultiple<long long>( long long value, long long multiple)
{
    if (multiple == 0.0l) return value;
    return static_cast<long long>(std::round(static_cast<long double>(value)/static_cast<long double>(multiple))*static_cast<long double>(multiple));
}

切り上げる関数を作成するには、を使用std::ceilし、常に切り捨てるにはを使用しますstd::floor。上記の私の例は、std::roundたです。

以下に示すように、「丸め」または「丸天井」と呼ばれるテンプレート関数を作成します。

template<typename T>
T roundCeilMultiple( T value, T multiple )
{
    if (multiple == 0) return value;
    return static_cast<T>(std::ceil(static_cast<double>(value)/static_cast<double>(multiple))*static_cast<double>(multiple));
}

以下に示すように、「切り捨て」または「ラウンドフロア」と呼ばれるテンプレート関数を作成します。

template<typename T>
T roundFloorMultiple( T value, T multiple )
{
    if (multiple == 0) return value;
    return static_cast<T>(std::floor(static_cast<double>(value)/static_cast<double>(multiple))*static_cast<double>(multiple));
}

1
プラス1。ただし、複数の== 0の場合に0を返すほうがより
適切であると考える人

3
int64_tをdoubleに変換すると損失が生じる可能性があるため、表示されるほど一般的な型ではないことに注意してください。
エイドリアンマッカーシー

@AdrianMcCarthyはい、上記のように正しいテンプレート特殊化を作成する必要があります。ご覧のとおり、long longおよびの2つの追加関数を実装していlong doubleます。他の2つの機能についても同じことを明らかにする必要があります。
Flovdis、2015年

これはすべての中で最も遅いと思いますが、そうである必要はありません。std :: enable_if_tを実行し、整数と浮動小数点に対して2つの分岐を行うだけです。また、numeric_limitsをより適切に使用して、仮数が実際に値を収めるのに十分な大きさかどうかを確認することもできます。それは安全に追加されます。

5

まず、エラー条件(複数の== 0)にはおそらく戻り値が必要です。何?知りません。多分あなたは例外を投げたい、それはあなた次第です。しかし、何も返さないと危険です。

次に、numToRoundがまだ倍数でないことを確認する必要があります。そうしないと、に追加multipleしたときroundDownに、間違った答えが返されます。

第三に、あなたのキャストは間違っています。numToRound整数にキャストしましたが、すでに整数になっています。除算の前にdoubleにキャストし、乗算の後にintにキャストする必要があります。

最後に、負の数に何をしたいですか?「切り上げ」は、ゼロへの丸め(正の数と同じ方向への丸め)、またはゼロからの丸め(「より大きい」負の数)を意味します。または、気にしないかもしれません。

ここに最初の3つの修正を含むバージョンがありますが、私は否定的な問題を扱いません:

int roundUp(int numToRound, int multiple)
{
 if(multiple == 0)
 {
  return 0;
 }
 else if(numToRound % multiple == 0)
 {
  return numToRound
 }

 int roundDown = (int) (( (double) numToRound / multiple ) * multiple);
 int roundUp = roundDown + multiple; 
 int roundCalc = roundUp;
 return (roundCalc);
}

@ピーターですか?私はそれint / intが私たちが望んでいたものではないintを返すと仮定しました。
Mike Caron、

int / intは確かにintを返しますが、それがまさにあなたが望んでいることです。例えば、numToRound = 7、複数= 3 7月3日= 2
ピーターRuderman氏

4

2の累乗に丸める:

ちょうど誰かが正の数の2の累乗の最も近い倍数に丸められた解決策を必要とする場合に備えて(それが私がここで終わった方法だからです):

// number: the number to be rounded (ex: 5, 123, 98345, etc.)
// pow2:   the power to be rounded to (ex: to round to 16, use '4')
int roundPow2 (int number, int pow2) {
    pow2--;                     // because (2 exp x) == (1 << (x -1))
    pow2 = 0x01 << pow2;

    pow2--;                     // because for any
                                //
                                // (x = 2 exp x)
                                //
                                // subtracting one will
                                // yield a field of ones
                                // which we can use in a
                                // bitwise OR

    number--;                   // yield a similar field for
                                // bitwise OR
    number = number | pow2;
    number++;                   // restore value by adding one back

    return number;
}

入力数がすでに倍数である場合、入力数は同じままです。

これは、GCCが-O2or -Os(9Sep2013 Build-godbolt GCC online)を使用して提供するx86_64出力です。

roundPow2(int, int):
    lea ecx, [rsi-1]
    mov eax, 1
    sub edi, 1
    sal eax, cl
    sub eax, 1
    or  eax, edi
    add eax, 1
    ret

コードの各C行は、アセンブリ内の行と完全に対応しています。http//goo.gl/DZigfX

これらの各命令は非常に高速なので、関数も非常に高速です。コードはとても小さくて速いので、それinlineを使用するときに関数に役立つかもしれません。


クレジット:


1
まさに私が探していたもの。ありがとう!
kiyo 2014年

1
int roundUpPow2(int num、int pow2){return num +(pow2-1)&〜(pow2-1); }(あなたはない4 16の倍数に丸める最大16を通る約30%高速で、かつ使いやすい
アクセルRietschin

3

私が使用しています:

template <class _Ty>
inline _Ty n_Align_Up(_Ty n_x, _Ty n_alignment)
{
    assert(n_alignment > 0);
    //n_x += (n_x >= 0)? n_alignment - 1 : 1 - n_alignment; // causes to round away from zero (greatest absolute value)
    n_x += (n_x >= 0)? n_alignment - 1 : -1; // causes to round up (towards positive infinity)
    //n_x += (_Ty(-(n_x >= 0)) & n_alignment) - 1; // the same as above, avoids branch and integer multiplication
    //n_x += n_alignment - 1; // only works for positive numbers (fastest)
    return n_x - n_x % n_alignment; // rounds negative towards zero
}

そして2の累乗について:

template <class _Ty>
bool b_Is_POT(_Ty n_x)
{
    return !(n_x & (n_x - 1));
}

template <class _Ty>
inline _Ty n_Align_Up_POT(_Ty n_x, _Ty n_pot_alignment)
{
    assert(n_pot_alignment > 0);
    assert(b_Is_POT(n_pot_alignment)); // alignment must be power of two
    -- n_pot_alignment;
    return (n_x + n_pot_alignment) & ~n_pot_alignment; // rounds towards positive infinity (i.e. negative towards zero)
}

これらの両方は負の値をゼロに向かって丸めます(つまり、すべての値を正の無限大に丸めます)。どちらも符号付きオーバーフローに依存していません(C / C ++では未定義)。

これは与える:

n_Align_Up(10, 100) = 100
n_Align_Up(110, 100) = 200
n_Align_Up(0, 100) = 0
n_Align_Up(-10, 100) = 0
n_Align_Up(-110, 100) = -100
n_Align_Up(-210, 100) = -200
n_Align_Up_POT(10, 128) = 128
n_Align_Up_POT(130, 128) = 256
n_Align_Up_POT(0, 128) = 0
n_Align_Up_POT(-10, 128) = 0
n_Align_Up_POT(-130, 128) = -128
n_Align_Up_POT(-260, 128) = -256

n_Align_Up_POTDelphiのTListクラスで見たときからずっと使っています。アライメント(倍数)が2の累乗になるなどの制限がありますが、SMIDの正しいアライメントを取得/確認するためにほとんど使用するため、これはほとんど問題になりません。それは素晴らしく、それについて多くの人が知らないようです。
user1593842 2017

2

おそらく、floatにキャストしてceil()を使用する方が安全です。int除算が正しい結果を生成することがわかっている場合を除きます。


1
doubleは、x86ベースのマシンで54ビットの仮数しか保持できないことに注意してください。64ビットの整数がある場合、最終的に失敗します。

IEEE754標準doubleはできませんが、x64 cpusには80ビットの内部浮動小数点があるため、単一の数値に対する演算は信頼できます
Martin Beckett

1
それは真実ですが、C / C ++からの丸めをほとんど制御できません。これはコントロールワードの設定に依存し、実際には80ビット未満に丸められる場合があります。また、そのような拡張中間体を持たないSSEおよびその他のSIMD命令セットもあります(ベクトル化コンパイラーはそれらを簡単に使用できます)。

2
int noOfMultiples = int((numToRound / multiple)+0.5);
return noOfMultiples*multiple

C ++は各数値を切り捨てるため、0.5を追加すると(1.5の場合は2になります)、1.49は1.99になるため、1になります。

編集-切り上げたくなかったので申し訳ありません。+ 0.5の代わりにceil()メソッドを使用することをお勧めします


2

一つには、私があなたが何をしたいのか本当に理解していないので、行

int roundUp = roundDown + multiple;
int roundCalc = roundUp;
return (roundCalc); 

間違いなく短くすることができます

int roundUp = roundDown + multiple;
return roundUp;

2

これは役立つかもしれません:

int RoundUpToNearestMultOfNumber(int val, int num)
{
  assert(0 != num);
  return (floor((val + num) / num) * num);
}

床と整数の除算を使用する理由 床には何もありません。それが二重の場合、少なくとも負の値の処理を継承できます。

2

常に切り上げる

int alwaysRoundUp(int n, int multiple)
{
    if (n % multiple != 0) {
        n = ((n + multiple) / multiple) * multiple;

        // Another way
        //n = n - n % multiple + multiple;
    }

    return n;
}

alwaysRoundUp(1、10)-> 10

alwaysRoundUp(5、10)-> 10

alwaysRoundUp(10、10)-> 10


常に切り捨てる

int alwaysRoundDown(int n, int multiple)
{
    n = (n / multiple) * multiple;

    return n;
}

alwaysRoundDown(1、10)-> 0

alwaysRoundDown(5、10)-> 0

alwaysRoundDown(10、10)-> 10


通常の方法で丸める

int normalRound(int n, int multiple)
{
    n = ((n + multiple/2)/multiple) * multiple;

    return n;
}

normalRound(1、10)-> 0

normalRound(5、10)-> 10

normalRound(10、10)-> 10


2

2のべき乗である最も近い倍数に丸める

unsigned int round(unsigned int value, unsigned int multiple){
    return ((value-1u) & ~(multiple-1u)) + multiple;
}

これは、必要な丸めの増分が2の累乗であるキャッシュラインに沿って割り当てる場合に役立ちますが、結果の値はその倍数である必要があります。gccこの関数の本体分割又は枝なし8つのアセンブリ命令を生成します。

round(  0,  16) ->   0
round(  1,  16) ->  16
round( 16,  16) ->  16
round(257, 128) -> 384 (128 * 3)
round(333,   2) -> 334

1

上記の投稿に似たアルゴリズムを見つけました。

int [(| x | + n-1)/ n] * [(nx)/ | x |]。ここで、xはユーザー入力値で、nは使用される倍数です。

これは、すべての値xに対して機能します。xは整数(ゼロを含む正または負)です。特にC ++プログラム用に作成しましたが、これは基本的にどの言語でも実装できます。


1

負のnumToRoundの場合:

これを行うのは本当に簡単なはずですが、標準のモジュロ%演算子は、予想されるような負の数を処理しません。たとえば、-14%12 = -2であり、10ではありません。最初に行うことは、負の数を返さないモジュロ演算子を取得することです。そうすれば、roundUpは本当に簡単です。

public static int mod(int x, int n) 
{
    return ((x % n) + n) % n;
}

public static int roundUp(int numToRound, int multiple) 
{
    return numRound + mod(-numToRound, multiple);
}

1

これは私がすることです:

#include <cmath>

int roundUp(int numToRound, int multiple)
{
    // if our number is zero, return immediately
   if (numToRound == 0)
        return multiple;

    // if multiplier is zero, return immediately
    if (multiple == 0)
        return numToRound;

    // how many times are number greater than multiple
    float rounds = static_cast<float>(numToRound) / static_cast<float>(multiple);

    // determine, whether if number is multiplier of multiple
    int floorRounds = static_cast<int>(floor(rounds));

    if (rounds - floorRounds > 0)
        // multiple is not multiplier of number -> advance to the next multiplier
        return (floorRounds+1) * multiple;
    else
        // multiple is multiplier of number -> return actual multiplier
        return (floorRounds) * multiple;
}

コードは最適ではないかもしれませんが、私はドライなパフォーマンスよりもクリーンなコードを好みます。


をキャストするintと、floatすぐに精度が失われ、不正解になります。
chux-モニカを

1
int roundUp (int numToRound, int multiple)
{
  return multiple * ((numToRound + multiple - 1) / multiple);
}

ただし:

  • 負の数では機能しません
  • numRound +複数のオーバーフローの場合は機能しません

オーバーフローの振る舞いを定義した、符号なし整数の代わりに使用することをお勧めします。

複数の== 0である例外が発生しますが、いずれにしても、明確に定義された問題ではありません。


1

c:

int roundUp(int numToRound, int multiple)
{
  return (multiple ? (((numToRound+multiple-1) / multiple) * multiple) : numToRound);
}

そしてあなたの〜/ .bashrcのために:

roundup()
{
  echo $(( ${2} ? ((${1}+${2}-1)/${2})*${2} : ${1} ))
}

1

xが倍数である場合、剰余の加算を無効にするために係数の組み合わせを使用します。

int round_up(int x, int div)
{
    return x + (div - x % div) % div;
}

余りの逆数を見つけてから、それが約数である場合はそれを無効にする係数で再度モジュラスしxます。

round_up(19, 3) = 21

1

OPの提案に基づく私の解決策と、他のすべての人からの例を以下に示します。ほとんどの人が負の数を処理するためにそれを探していたので、このソリューションは特別な関数、つまりabsなどを使用せずにそれを実行します。

係数を回避し、代わりに除算を使用することにより、切り捨てられますが、負の数は自然な結果になります。切り捨てバージョンが計算された後、負または正のいずれかの方向に切り上げるために必要な計算が行われます。

また、何かを計算するために特別な関数は使用されないため、速度が少し向上することに注意してください。

int RoundUp(int n, int multiple)
{
    // prevent divide by 0 by returning n
    if (multiple == 0) return n;

    // calculate the rounded down version
    int roundedDown = n / multiple * multiple;

    // if the rounded version and original are the same, then return the original
    if (roundedDown == n) return n;

    // handle negative number and round up according to the sign
    // NOTE: if n is < 0 then subtract the multiple, otherwise add it
    return (n < 0) ? roundedDown - multiple : roundedDown + multiple;
}

で失敗するRoundUp(INT_MIN, -1)ようn / multipleであるintオーバーフロー。
chux-モニカを

1

これが役立つと思います。以下のプログラムをC言語で記述しました。

# include <stdio.h>
int main()
{
  int i, j;
  printf("\nEnter Two Integers i and j...");
  scanf("%d %d", &i, &j);
  int Round_Off=i+j-i%j;
  printf("The Rounded Off Integer Is...%d\n", Round_Off);
  return 0;
}

0
/// Rounding up 'n' to the nearest multiple of number 'b'.
/// - Not tested for negative numbers.
/// \see http://stackoverflow.com/questions/3407012/
#define roundUp(n,b) ( (b)==0 ? (n) : ( ((n)+(b)-1) - (((n)-1)%(b)) ) )

/// \c test->roundUp().
void test_roundUp() {   
    // yes_roundUp(n,b) ( (b)==0 ? (n) : ( (n)%(b)==0 ? n : (n)+(b)-(n)%(b) ) )
    // yes_roundUp(n,b) ( (b)==0 ? (n) : ( ((n + b - 1) / b) * b ) )

    // no_roundUp(n,b) ( (n)%(b)==0 ? n : (b)*( (n)/(b) )+(b) )
    // no_roundUp(n,b) ( (n)+(b) - (n)%(b) )

if (true) // couldn't make it work without (?:)
{{  // test::roundUp()
    unsigned m;
                { m = roundUp(17,8); } ++m;
    assertTrue( 24 == roundUp(17,8) );
                { m = roundUp(24,8); }
    assertTrue( 24 == roundUp(24,8) );

    assertTrue( 24 == roundUp(24,4) );
    assertTrue( 24 == roundUp(23,4) );
                { m = roundUp(23,4); }
    assertTrue( 24 == roundUp(21,4) );

    assertTrue( 20 == roundUp(20,4) );
    assertTrue( 20 == roundUp(19,4) );
    assertTrue( 20 == roundUp(18,4) );
    assertTrue( 20 == roundUp(17,4) );

    assertTrue( 17 == roundUp(17,0) );
    assertTrue( 20 == roundUp(20,0) );
}}
}

0

これは、正の整数を求めている結果を得ています。

#include <iostream>
using namespace std;

int roundUp(int numToRound, int multiple);

int main() {
    cout << "answer is: " << roundUp(7, 100) << endl;
    cout << "answer is: " << roundUp(117, 100) << endl;
    cout << "answer is: " << roundUp(477, 100) << endl;
    cout << "answer is: " << roundUp(1077, 100) << endl;
    cout << "answer is: " << roundUp(52,20) << endl;
    cout << "answer is: " << roundUp(74,30) << endl;
    return 0;
}

int roundUp(int numToRound, int multiple) {
    if (multiple == 0) {
        return 0;
    }
    int result = (int) (numToRound / multiple) * multiple;
    if (numToRound % multiple) {
        result += multiple;
    } 
    return result;
}

そしてここに出力があります:

answer is: 100
answer is: 200
answer is: 500
answer is: 1100
answer is: 60
answer is: 90

0

私はこれがうまくいくと思います:

int roundUp(int numToRound, int multiple) {
    return multiple? !(numToRound%multiple)? numToRound : ((numToRound/multiple)+1)*multiple: numToRound;
}

-1

これは私にとっては機能しますが、ネガを処理しようとしませんでした

public static int roundUp(int numToRound, int multiple) {
    if (multiple == 0) {
        return 0;
    } else if (numToRound % multiple == 0) {
    return numToRound;
    }

    int mod = numToRound % multiple;
    int diff = multiple - mod;
    return numToRound + diff;
}

-2

エレガンスのコンセプトを示す非常にシンプルなソリューションを次に示します。基本的にはグリッドスナップ用です。

(疑似コード)

nearestPos = Math.Ceil( numberToRound / multiple ) * multiple;

提出前にアイデアを確認しましたか?それは正しい答えを
yaodav

それも有効なコードではありません。
user13783520
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.