アットウィキロゴ

GMPを使ってDBL_MAXの文字列をdoubleに変換するルーチン

  1. /*
  2.  
  3.   dbl_max_gmp.c
  4.  
  5.   GMPを用いて、DBL_MAXの値(10進数文字列)をdoubleに変換する。
  6.  
  7.   コンパイル:
  8.   % cl /Ic:\include dbl_max_gmp.c gmp.lib /link /LIBPATH:c:\lib
  9.  
  10.   実行例:
  11.   % ./dbl_max_gmp
  12.   mpf = 0.17976931348623158e309
  13.   double = 1.79769313486231570e+308
  14.  
  15.  */
  16.  
  17. #include <stdio.h>
  18. #include <float.h>
  19. #include <string.h>
  20. #include "gmp.h"
  21.  
  22. #define LOG_TEN_TWO 3.32192809488736234789
  23. #define bprec(n) (int)(((n+10)*LOG_TEN_TWO)+2)
  24.  
  25. void atompf(char s[], mpf_t mp);
  26.  
  27. main()
  28. {
  29. mpf_t f;
  30. long prec, dprec;
  31.  
  32. dprec = 1000L; /* decimal precision */
  33. prec = bprec(dprec); /* binary precision (plus alpha) */
  34. mpf_set_default_prec(prec);
  35.  
  36. mpf_init(f);
  37. atompf("1.7976931348623158e+308", f); /* DBL_MAX in Visual C++ */
  38.  
  39. printf(" mpf = ");
  40. mpf_out_str(stdout, 10, dprec + 10, f);
  41. putchar('\n');
  42. printf("double = %25.17e\n", mpf_get_d(f));
  43.  
  44. return 0;
  45. }
  46.  
  47. /* atompf: convert a string into multi-precision floating-point */
  48. void atompf(char s[], mpf_t f)
  49. {
  50. int i, c, exp;
  51. int frc_sign, frc_exp, exp_sign, exp_exp;
  52. mpz_t mp_frc, mp_var, mp_exp;
  53. mpf_t mp_fp1, mp_fp2, mp_fp3;
  54.  
  55. /* init */
  56. mpz_init(mp_frc);
  57. mpz_init(mp_var);
  58. mpz_init(mp_exp);
  59. mpf_init(mp_fp1);
  60. mpf_init(mp_fp2);
  61. mpf_init(mp_fp3);
  62.  
  63. /* skip leading blanks */
  64. for (i=0; isspace(s[i]); i++)
  65. ;
  66.  
  67. /* sign */
  68. frc_sign = 1;
  69. if ((c = s[i]) == '-')
  70. frc_sign = -1;
  71. if (c == '-' || c == '+')
  72. i++;
  73.  
  74. /* integral part */
  75. mpz_set_ui(mp_frc, 0);
  76. for (; isdigit(s[i]); i++) {
  77. mpz_mul_ui(mp_var, mp_frc, 10);
  78. mpz_add_ui(mp_frc, mp_var, s[i] - '0');
  79. }
  80.  
  81. /* fractional part */
  82. if (s[i] == '.') {
  83. frc_exp = 0;
  84. for (i++; isdigit(s[i]); i++) {
  85. mpz_mul_ui(mp_var, mp_frc, 10);
  86. mpz_add_ui(mp_frc, mp_var, s[i] - '0');
  87. frc_exp++;
  88. }
  89. }
  90.  
  91. /* exponential part */
  92. if ((c = toupper(s[i])) == 'E' || c == 'D')
  93. i++;
  94. exp_sign = 1;
  95. if ((c = s[i]) == '-')
  96. exp_sign = -1;
  97. if (c == '+' || c == '-')
  98. i++;
  99. exp_exp = 0;
  100. for (; isdigit(s[i]); i++) {
  101. exp_exp = 10 * exp_exp + (s[i] - '0');
  102. }
  103.  
  104. /* add exponent and store its power in mp_exp */
  105. exp = exp_sign * exp_exp - frc_exp;
  106. if (exp > 0)
  107. exp_sign = 1;
  108. else {
  109. exp_sign = -1;
  110. exp = -exp;
  111. }
  112. mpz_set_ui(mp_exp, 1);
  113. for (; exp > 0; exp--) {
  114. mpz_mul_ui(mp_var, mp_exp, 10);
  115. mpz_swap(mp_exp, mp_var);
  116. }
  117.  
  118. /* build a mpf_t value */
  119. mpf_set_z(mp_fp1, mp_frc);
  120. mpf_set_z(mp_fp2, mp_exp);
  121. if (exp_sign > 0) {
  122. mpf_mul(mp_fp3, mp_fp1, mp_fp2);
  123. } else {
  124. mpf_div(mp_fp3, mp_fp1, mp_fp2);
  125. }
  126.  
  127. /* copy */
  128. mpf_set(f, mp_fp3);
  129.  
  130. /* clear */
  131. mpz_clear(mp_frc);
  132. mpz_clear(mp_exp);
  133. mpz_clear(mp_var);
  134. mpf_clear(mp_fp1);
  135. mpf_clear(mp_fp2);
  136. mpf_clear(mp_fp3);
  137. }
  138.  
最終更新:2008年03月15日 10:40
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。