web-dev-qa-db-ja.com

Cの浮動小数点数から小数部分を抽出します

浮動小数点数の小数部分を抽出し、小数部分と整数部分を2つの別々の整数変数に格納するにはどうすればよいですか?

43
Binu

modf関数を使用します。

double integral;
double fractional = modf(some_double, &integral);

整数にキャストすることもできますが、整数がオーバーフローする可能性があることに注意してください。結果は予測できません。

これを試して:

int main() {
  double num = 23.345;
  int intpart = (int)num;
  double decpart = num - intpart;
  printf("Num = %f, intpart = %d, decpart = %f\n", num, intpart, decpart);
}

私にとって、それは以下を生成します:

Num = 23.345000, intpart = 23, decpart = 0.345000

それはあなたが求めているもののようです。

44
Chris Bunch

簡単な「一言で言えば」最も明白な答えは次のようなものです。

#define N_DECIMAL_POINTS_PRECISION (1000) // n = 3. Three decimal points.

float f = 123.456;
int integerPart = (int)f;
int decimalPart = ((int)(f*N_DECIMAL_POINTS_PRECISION)%N_DECIMAL_POINTS_PRECISION);

N_DECIMAL_POINTS_PRECISIONをニーズに合わせて変更することにより、必要な小数点の数を変更します。

15

この場合、小数部分の桁数がアプリオリにわからないため、文字列を使用するのが正しい方法だと思います。ただし、@ SingleNegationEliminationで前述したように、すべてのケース(1.005など)で機能するわけではありません。これについての私の見解は次のとおりです。

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

int main(void)
{
    char s_value[60], s_integral[60], s_fractional[60];
    int i, found = 0, count = 1, integral, fractional;

    scanf("%s", s_value);

    for (i = 0; s_value[i] != '\0'; i++)
    {
        if (!found)
        {
            if (s_value[i] == '.')
            {
                found = 1;
                s_integral[i] = '\0';
                continue;
            }
            s_integral[i] = s_value[i];
            count++;
        }
        else
            s_fractional[i - count] = s_value[i];
    }
    s_fractional[i - count] = '\0';

    integral = atoi(s_integral);
    fractional = atoi(s_fractional);
    printf("value = %s, integral = %d, fractional = %d\n",
        s_value, integral, fractional);

    return 0;
}
3
B. Silva

ダブルフロートを使用してサブルーチンを作成し、2つの整数値を返します。


void double2Ints(double f, int p, int *i, int *d)
{ 
  // f = float, p=decimal precision, i=integer, d=decimal
  int   li; 
  int   prec=1;

  for(int x=p;x>0;x--) 
  {
    prec*=10;
  };  // same as power(10,p)

  li = (int) f;              // get integer part
  *d = (int) ((f-li)*prec);  // get decimal part
  *i = li;
}

void test()
{ 
  double df = 3.14159265;
  int   i,d;
  for(int p=2;p<9;p++)
  {
    double2Ints(df, p, &i,&d); printf("d2i (%d) %f = %d.%d\r\n",p, df,i,d);
  }
}
1
mrwes

私もその方法を考えていました。しかし、私は方法を見つけました。このコードを試してください

printf("Enter a floating number");
scanf("%d%c%d", &no, &dot, &dec);
printf("Number=%d Decimal part=%d", no, dec);

出力:-

Enter a floating number
23.13
Number=23 Decimal part=13
1
Abi

浮動小数点数を使用してfloored値を減算し、小数部分を取得します。

double fractional = some_double - floor(some_double);

これにより、整数への型キャストが防止されます。これにより、浮動小数点数が非常に大きく、整数値にそれを含めることさえできない場合、overflowが発生する可能性があります。

また、負の値の場合、このコードは、正の小数部floor()入力値以下の最大整数値を計算 からの浮動小数点数。

0
0xAA55
 #include <stdio.h>
Int main ()
{
float f=56.75;
int a=(int)f;
int result=(f-a)*100;
printf ("integer = %d\n decimal part to integer 
 =%d\n",result);
}
Output:- 
integer =56
decimal part to integer = 75
0
Shravani

Aが整数で、(int)Aの場合、数値を整数にキャストして整数部分になることを意味し、もう一方は(A-(int)A)* 10 ^ nです。ここで、nは保持する小数の数です。 。

0
Edahi

別の方法を次に示します。

#include <stdlib.h>
int main()
{
    char* inStr = "123.4567";         //the number we want to convert
    char* endptr;                     //unused char ptr for strtod

    char* loc = strchr(inStr, '.');
    long mantissa = strtod(loc+1, endptr);
    long whole = strtod(inStr, endptr);

    printf("whole: %d \n", whole);     //whole number portion
    printf("mantissa: %d", mantissa);  //decimal portion

}

http://codepad.org/jyHoBAL

出力:

whole: 123 
mantissa: 4567
0
dukevin

最初の10進数値を取得するだけの場合、解決策は非常に簡単です。

説明例を次に示します

int leftSideOfDecimalPoint = (int) initialFloatValue; // The cast from float to int keeps only the integer part

int temp = (int) initialFloatValue * 10;
int rightSideOfDecimalPoint = temp % 10;

たとえば、27.8の初期float値があるとします。

  • 初期のfloat値をintにキャストするだけで、小数部は破棄され、整数部のみが保持されます。
  • 初期フロート値に10を掛けると、278.0の結果が得られ、この結果をintにキャストすると、278の値が得られます。
  • 278を10で割ると、27.8が得られます。残りは8で、小数点の右側の値です。したがって、モジュラスを使用します。

次に、この手法を使用して、たとえば10の代わりに100などを使用して、次の小数点文字を取得できます。


7セグメントディスプレイに表示するなど、リアルタイムシステムでこの手法を使用する場合、浮動小数点値で乗算するため、乗算に多くのオーバーヘッド時間がかかるため、正しく機能しない可能性があることに注意してください。

0
Wilhelm