2009-05-17 7 views
2

組み込みの天井または床のファンクションを使用せずに、数値を最も近い整数に丸めるために必要な分数を数値に追加するのに必要な分数を決定する良いアルゴリズムとは何ですか?分数の質問

編集:数を最も近い整数に丸めるために必要な部分を把握するための数学的な番号を探します。より原始的な数学演算が良い。他の手順は使用しないでください。あなたの方法に合っていれば、どちらでも0.5を取ることができます。これは私の宿題に関する質問ではなく、どこでも使用するつもりはありません。 0.5による

+0

標準のAPIから他の機能を使用できますか?または、ホイールを再実装することを意味していても、実際に独自のアルゴリズムを実装したいのですか? –

+0

intにキャストできますか?または、それは組み込みのフロア関数としてカウントされますか? – DeadHead

+0

申し訳ありません。鋳物はありません。 – unj2

答えて

4

のModその>が0.5ならば、小数部分を取得するための1と番号、切り上げ、他のラウンドダウン

OR

分割数、その奇数、切り上げ、そうでない場合はラウンドダウン

+1

一部の言語では、整数にmod /%しか定義していないことに注意してください。 – Stephan202

+0

アルゴリズムがx%1> = 0.5 プリント((X-X%1)+ 1) 他 印刷のx%1 エンドを-x場合 巧妙であるあなたは、%なしanothersolutionを考えていただけますか? – unj2

+0

他の制約はありますか?トリックを分けるのだろうか? – Simonw

3

あなたは(それが唯一の言語で整数のために定義される可能性がありますので、あなたはCっぽい擬似コードでこのような何かを(行うことができるかもしれない)のmodを使用できない場合:

// make the input positive: 
boolean inputPositive = true; 
if (input < 0) { 
    input = 0 - input; 
    inputPositive = false; 
} 

// subtract 1 until you just have the decimal portion: 
int integerPart = 0; 
while (input > 1) { 
    input = input - 1; 
    integerPart++; 
} 

int ret; 
if (input >= 0.5) { // round up 
    ret = integerPart + 1; 
} else { 
    ret = integerPart; 
} 

if (inputPositive) { 
    return ret; 
} else { 
    return 0 - ret; 
} 

この解決法は、modまたは外部関数を使用しません。もちろん、私はあなたがなぜこれを実生活で望んでいるのか想像できません。しかし、考えてみると面白いです。

+1

私によれば、すべての要件に従ってください。 :-) –

+0

+1もちろん、私は言及を忘れて.. ;-) –

+1

+1。あなたは2つの小さな累乗を減算することでこれを改善することができます。そのため、この手順も大きな入力に対して妥当な時間内に終了します。 – Stephan202

3

数値の小数部分を取得すると、問題はかなり解決されます。小数点以下の部分を得る1つの方法は、あなたの数から2のべき乗を繰り返し減算することです(最初は負であれば正であったと仮定します)。

以下の関数getWholeMakerは、あなたが望むもの(数字の周りに追加する必要があるもの)を返します。実行時間はO(log(n))で、基本操作のみを使用します。

/* Returns the factional part of x */ 
double getFrac(double x) { 
    if(x < 0) x = -x; 
    if(x < 1) return x; 
    else if(x < 2) return x-1; 

    /* x >= 0 */ 
    double t = 2; 
    while(t+t <= x) t += t; 
    /* t is now the largest power of 2 less than or equal to x */ 
    while(t >= 1) { 
     if(t <= x) x -= t; 
     t /= 2; 
    } 

    return x; 
} 

double getWholeMaker(double x) { 
    double frac = getFrac(x); 
    double sign = x >= 0 ? +1 : -1; 
    return sign * (frac <= 0.5 ? -frac : 1-frac); 
} 
+0

甘い。しかし、これはpkaedingのアルゴリズムが最適化されたように見えます。私は正しいですか? – unj2

+0

はい、それはpkaedingのようですが、対数時間で動作します(pkaedingは線形時間です)。 –