3

ascii "15605632.68128593" があり、accurary を失うことなく double に変換したい -

 so 
 double d;
 d=(double)atof("15605632.68128593");
 printf("%f",d);

 printed result is 15605632.681286

何か案は ?

ありがとう - !

4

3 に答える 3

7

末尾の小数点以下の桁数をすべて取得していない可能性があります。試してみてくださいprintf("%.8f", d)

sscanf("15605632.68128593", "%lf", &d)電話の代わりに試すこともできatofます。

atoftoの結果をキャストする必要もありませんdouble。もうダブルです。しかし、キャストに害はありません。

少なくとも約 6 年前、私がこれを詳細に調べたとき、多くprintfscanf実装は、あなたが想定するほど完全な逆関数として機能しないという意味でバグが多かったことに注意してください。Visual C/C++ と gcc はどちらもネイティブ実装に問題がありました。 この論文は有用な参考文献です。

Cygwin と gcc 4.3.4:

#include <stdio.h>

int main(void)
{
  double x;

  sscanf("15605632.68128593", "%lf", &x);
  printf("%.8f\n", x);
  return 0;
}

その後:

# gcc foo.c
# ./a
15605632.68128593
于 2013-06-13T01:39:48.947 に答える
4

目標:精度を失うことなく "15605632.68128593" を double に変換します

atof()プログラムができる最善の方法でそれを達成しました。しかし、15605632.68128593(16 桁の数字) は ではとして正確に表現できないためdoubleCに近似されました1.560563268128593080...e+07。したがって、わずかな損失ではありますが、精度が失われました。

Typical doubleは、約 2 64の異なる数値を表すことができます。参考までに、近くの候補と OP の文字列を以下に示します。

 15605632.68128592893...  previous double
"15605632.68128593"
 15605632.68128593080...  closest double

印刷しようとすると、印刷されたものが の正確な値であると考えて、悲しみが生じますx。代わりに、丸められた値が出力されました。指定子を使用すると、%fデフォルトで「.」の右側の 6 桁になります。報告され15605632.681286た 14 桁の数字を指定します。

すべての有効桁数をすべて表示するより良い方法は、 でフォーマットdoubleを使用することです。 '.' の右側の最大桁数であり、10 進指数表記で、a を「往復」するのに必要なすべての桁を示します(文字列の違いなしに、文字列から倍精度文字列へ)。'.' の左側には常に 1 桁が表示されるため、以下の出力では有効数字が表示されます。 私の鉱山と多くの環境では15ですが、さまざまです。%eDBL_DIGDBL_DIG %edouble%e1 + DBL_DIGDBL_DIGC

すべての有効数字を表示したい場合は、 what is significantを修飾する必要があります。このnextafter()関数は、次の表現可能な を示しますdouble。そのため、少なくとも x と次の x を区別するのに十分な桁数を表示したい場合があります。私はお勧めしDBL_DIG + 2ます。DBL_DIG十分かもしれませんが 。詳細

プログラムが使用した正確"1.560563268128593e+07"値は15605632.68128593079745769500732421875. これらすべての数字を表示する必要がある状況はほとんどありません。多くの数字を要求しても、ある時点でprintf()ゼロが返されます。

#include <stdio.h>
#include <float.h>
#include <tgmath.h>

int main(int argc, char *argv[]) {
  double x;
  x = atof("15605632.68128593");
  printf("%.*le\n",DBL_DIG, x); // All digits "round-trip" string-to-double-string w/o loss
  printf("%.*le\n",DBL_DIG + 1, x);  // All the significant digit "one-way" double-string
  printf("%.*le\n",DBL_DIG + 1, nextafter(x, 2*x)); // The next representable double
  printf("%.*le\n",DBL_DIG + 3, x);  // What happens with a few more
  printf("%.*le\n",DBL_DIG + 30, x); // What happens if you are a bit loony
  return 0;
}

1.560563268128593e+07
1.5605632681285931e+07
1.5605632681285933e+07
1.560563268128593080e+07
1.560563268128593079745769500732421875000000000e+07
于 2013-06-13T07:40:24.813 に答える