26

C で float を丸める関数はありますか、それとも自分で書く必要がありますか?

フロート変換 = 45.59 2346543;

実際の値を小数点以下 1 桁に丸めたいのですが、conver = 45. 6 .

4

7 に答える 7

31

確かに、roundf()を使用できます。小数点以下 1 桁に丸めたい場合は、次のようにします。roundf(10 * x) / 10

于 2009-01-30T20:08:15.807 に答える
31

Rob が述べたように、浮動小数点数を小数点以下 1 桁まで出力したいだけでしょう。この場合、次のようなことができます。

#include <stdio.h>
#include <stdlib.h>

int main()
{
  float conver = 45.592346543;
  printf("conver is %0.1f\n",conver);
  return 0;
}

格納された値を実際に丸めたい場合は、もう少し複雑です。1 つには、小数点以下 1 桁の表現が浮動小数点で正確に類似することはめったにありません。できるだけ近づきたいだけなら、次のようなことがうまくいくかもしれません:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main()
{
  float conver = 45.592346543;
  printf("conver is %0.1f\n",conver);

  conver = conver*10.0f;
  conver = (conver > (floor(conver)+0.5f)) ? ceil(conver) : floor(conver);
  conver = conver/10.0f;

  //If you're using C99 or better, rather than ANSI C/C89/C90, the following will also work.
  //conver = roundf(conver*10.0f)/10.0f;

  printf("conver is now %f\n",conver);
  return 0;
}

この 2 番目の例は、あなたが探しているものではないと思いますが、完全を期すために含めました。出力だけでなく、内部的にこの方法で数値を表現する必要がある場合は、代わりに固定小数点表現を使用することを検討してください。

于 2009-01-30T20:19:19.327 に答える
2
#include <math.h>

double round(double x);
float roundf(float x);

-lm でリンクすることを忘れないでください。ceil()、floor()、および trunc() も参照してください。

于 2009-01-30T20:07:57.617 に答える
1

ロブの答えを少し一般化するために、出力でそれを行っていない場合でも、同じインターフェースをsprintf().

とはいえ、別の方法もあると思います。切り上げとceil()切り下げを試すことができます。floor()良いトリックは 0.5 を加算することです。0.5 を超えるものは切り上げられ、それ未満のものは切り捨てられます。ceil()ただし、 sでfloor()のみ動作しdoubleます。

編集:また、フロートの場合、フロートtruncf()を切り捨てるために使用できます。正確な丸めを行うには、同じ +0.5 トリックが機能するはずです。

于 2009-01-30T20:09:00.767 に答える
1

丸められた値を出力するには、@ Matt Jが質問によく答えます。

float x = 45.592346543;
printf("%0.1f\n", x);  // 45.6

ほとんどの浮動小数点 (FP) は2 進数ベースであるため、数学的に正しい答えが である場合、小数点以下1 桁に正確に丸めることはできません。x.1, x.2, ...

FP番号を最も近い 0.1ものに変換することは別の問題です。

オーバーフロー: 最初に 10 (または 100、1000 など) でスケーリングするアプローチは、大きなx.

float round_tenth1(float x) {
  x = x * 10.0f;
  ...
}

二重丸め: 0.5f を追加してから使用するとfloorf(x*10.0f + 0.5f)/10.0、中間の合計x*10.0f + 0.5fが新しい整数に切り上げられるときに間違った結果が返されます。

// Fails to round 838860.4375 correctly, comes up with 838860.5 
// 0.4499999880790710449 fails as it rounds to 0.5
float round_tenth2(float x) {
  if (x < 0.0) {
    return ceilf(x*10.0f + 0.5f)/10.0f;
  }
  return floorf(x*10.0f + 0.5f)/10.0f;
}

が よりもはるかに大きい場合、 へのキャストintは明らかな問題があります。float xINT_MAX


を使用してroundf()、家族で利用できるの<math.h>が最善の方法です。

float round_tenthA(float x) {
  double x10 = 10.0 * x;
  return (float) (round(x10)/10.0);
}

の使用を避けるdoubleには、数値を丸める必要があるかどうかを単純にテストします。

float round_tenthB(float x) {
  const float limit = 1.0/FLT_EPSILON;
  if (fabsf(x) < limit) {
    return roundf(x*10.0f)/10.0f;
  }
  return x;
}
于 2016-01-29T17:27:11.797 に答える
0

#define round(a) (int) (a+0.5) をマクロとして使用できるため、round(1.6) を記述するたびに 2 が返され、round(1.3) を記述するたびに 1 が返されます。

于 2015-04-15T02:57:32.383 に答える
0

double として表される最も近い整数に丸めるround()関数もあります。fround()しかし、それはあなたが望むものではありません。

私は同じ問題を抱えていて、これを書きました:

#include <math.h>

   double db_round(double value, int nsig)
/* ===============
**
** Rounds double <value> to <nsig> significant figures.  Always rounds
** away from zero, so -2.6 to 1 sig fig will become -3.0.
**
** <nsig> should be in the range 1 - 15
*/

{
    double     a, b;
    long long  i;
    int        neg = 0;


    if(!value) return value;

    if(value < 0.0)
    {
        value = -value;
        neg = 1;
    }

    i = nsig - log10(value);

    if(i) a = pow(10.0, (double)i);
    else  a = 1.0;

    b = value * a;
    i = b + 0.5;
    value = i / a;

    return neg ? -value : value;
} 
于 2014-05-22T17:22:53.290 に答える