【C言語】数値をfloatやdouble型を使わずに小数点を含む文字列に変換する方法

プログラマのメモ帳

この記事では、数値を小数点を含む文字列に変換する際にfloatやdouble型を使わない方法を紹介しています。

floatやdouble型を使った変換では誤差が生じてしまうため、それを防ぎつつ文字列化することが目的です。(※厳密な処理が必要な場合です。)

なお、この変換方法では数値と変換する小数点以下のケタ数を情報として持っている必要があります。

変換はソースコードのConvNumFew関数で行っています。

サンプルとして以下のような変換をしてみます。
123  →  -1.23
-1   → -0.01 

スポンサーリンク

Sample Code

#include <stdio.h>

//-----------------------------------------------------------------------------
//  関数名 :ConvNumFew
//  機  能 :数値を指定された小数点桁数の文字列に変換する
//  戻り値 :void
//-----------------------------------------------------------------------------
void ConvNumFew(
  char * cnfStr,                        /* o:変換した文字列 */
  int    dataVal,                       /* i:変換する数値 */
  int    keta                           /* i:小数点以下の桁数 */
)

{
  int   div = 0;
  int   rem = 0;
  int   minusFlag = 0;
  int   divVal = 1;
  int   tmpKeta;

  char  minus[2] = "-";
  char  period[2] = ".";
  char  divStr[32];
  char  remStr[32];

  char  cnfFormat[32];


  tmpKeta = keta;

  /* 割る数を求める(10~1000000000) */
  while(tmpKeta != 0)
  {
    divVal *= 10;
    tmpKeta--;
  }

  /* ケタ数に応じたフォーマットを作成する */
  sprintf(cnfFormat, "%%0%dd", keta);  //ケタ数だけゼロパディング

  div = (dataVal / divVal);        //商
  rem = (dataVal % divVal);        //余り

  if(div < 0)       //商がマイナスだった場合
  {
    rem *= -1;      //余りは正の値にする
  }
  else if(rem < 0)  //余りがマイナスだった場合
  {
    div *= -1;      //商を負の値にする
    rem *= -1;      //余りを正の値にする

    if(div == 0)    //商が0だったらマイナスにならないため強制的マイナス符号追加
    {
      minusFlag = 1; //フラグを立てる
    }

  }

  sprintf(divStr, "%d", div);       //商を文字列に変換
  sprintf(remStr, cnfFormat, rem);  //フォーマットで余りを文字列化

  if(minusFlag == 1)  //商が0かつマイナスの場合
  {
    sprintf(cnfStr, "%s", minus);  //マイナスを先頭に書込み
    strcat(cnfStr, divStr);
  }
  else
  {
    sprintf(cnfStr, "%s", divStr);
  }
  strcat(cnfStr, period);
  strcat(cnfStr, remStr);

}


//------------------------ main --------------------------------------------//
int main(void){

  int val_a = 123;  //変換する数値
  int val_b = -1;   //変換する数値
  int ketaNum = 2;  //少数点以下のケタ数
  char szStr[256];

  ConvNumFew(szStr, val_a, ketaNum);
  printf("%s\n", szStr);

  ConvNumFew(szStr, val_b, ketaNum);
  printf("%s\n", szStr);

}

ポイントはマイナス値の処理でしょう。特に商が0の場合には-1を掛けても0のままなので、強制的に「ー」符号を先頭に書き込む必要があります。

その他については、ケタ数に応じたフォーマットを作成してsprintf( )で文字列として書き込み、必要なピリオドと余りの文字列をstrcat( )で連結しています。

実行例

以上です。
参考になればうれしいです。

コメント

タイトルとURLをコピーしました