Advertisement
tyotyotyo

strtod

Apr 22nd, 2022
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.24 KB | None | 0 0
  1. /******************************************************************************
  2.  
  3.                             Online C Compiler.
  4.                 Code, Compile, Run and Debug C program online.
  5. Write your code in this editor and press "Run" button to compile and execute it.
  6.  
  7. *******************************************************************************/
  8.  
  9. #include <stdio.h>
  10.  
  11. #include <locale.h>
  12.  
  13. const double __stdlib_string_to_double_table[17] =
  14. {
  15.     0.0,
  16.     0.1,
  17.     0.01,
  18.     0.001,
  19.     0.0001,
  20.     0.00001,
  21.     0.000001,
  22.     0.0000001,
  23.     0.00000001,
  24.     0.000000001,
  25.     0.0000000001,
  26.     0.00000000001,
  27.     0.000000000001,
  28.     0.0000000000001,
  29.     0.00000000000001,
  30.     0.000000000000001,
  31.     0.0000000000000001,
  32. };
  33.  
  34. const int __stdlib_string_to_int_table_hex[6] =
  35. {
  36.     10, 11, 12, 13, 14, 15
  37. };
  38.  
  39. const long long __stdlib_string_to_double_table_hex[17] =
  40. {
  41.     1,
  42.     16,
  43.     256,
  44.     4096,
  45.     65536,
  46.     1048576,
  47.     16777216,
  48.     268435456,
  49.     4294967296,
  50.     68719476736,
  51.     1099511627776,
  52.     17592186044416,
  53.     281474976710656,
  54.     4503599627370496,
  55.     72057594037927936,
  56.     1152921504606846976,
  57.     -1,
  58. };
  59.  
  60. const char*
  61. __string_skip_spaces(const char* str)
  62. {
  63.     while (1)
  64.     {
  65.         if (*str > 0 && *str < 33)
  66.             ++str;
  67.         else
  68.             break;
  69.  
  70.         if (!*str)
  71.             break;
  72.     }
  73.     return str;
  74. }
  75.  
  76. double  
  77. strtod(const char* nptr, char** endptr)
  78. {
  79.     double result = 0.0;
  80.     long leftPart = 0;
  81.     long rightPart = 0;
  82.     int e_right = 0;
  83.     int flags = 0; /* 1(-) 2(hex) 3(e) 4(e-)*/
  84.  
  85.     const char* str_ptr = __string_skip_spaces(nptr);
  86.     const struct lconv* lc = localeconv();
  87.     char decimal_point = *lc->decimal_point;
  88.  
  89.     /*with - or not*/
  90.     if (*str_ptr == '-')
  91.     {
  92.         ++str_ptr;
  93.         flags |= 0x1;
  94.     }
  95.  
  96.     if (!*str_ptr)
  97.         goto end;
  98.  
  99.     /*hex or not, skip 00*/
  100.     if (*str_ptr == '0')
  101.     {
  102.         ++str_ptr;
  103.         if (!*str_ptr)
  104.             goto end;
  105.  
  106.         if (*str_ptr == 'x' || *str_ptr == 'X')
  107.         {
  108.             flags |= 0x2;
  109.             ++str_ptr;
  110.         }
  111.         else if (*str_ptr == decimal_point)
  112.             --str_ptr;
  113.         else if (*str_ptr < '1' || *str_ptr > '9')
  114.             goto end;
  115.     }
  116.  
  117.     if (!*str_ptr)
  118.         goto end;
  119.  
  120.     long part_2_count = 0;
  121.  
  122.     if (flags & 0x2)/*hex*/
  123.     {
  124.         int charNum = 0;
  125.         const unsigned char* save_str_ptr = str_ptr;
  126.         while (*str_ptr)
  127.         {
  128.             if ((*str_ptr >= 'a' && *str_ptr <= 'f')
  129.                 || (*str_ptr >= 'A' && *str_ptr <= 'F'))
  130.                 ++charNum;
  131.             else
  132.                 break;
  133.  
  134.             ++str_ptr;
  135.  
  136.             if (!*str_ptr)
  137.                 break;
  138.         }
  139.  
  140.         if (charNum)
  141.         {
  142.             str_ptr = save_str_ptr;
  143.             int charNum2 = charNum;
  144.             for (int i = 0; i < charNum; ++i)
  145.             {
  146.                 int curr_char = str_ptr[i];
  147.                 if (curr_char < 'a')
  148.                     curr_char += 32;
  149.  
  150.                 int curr_int = __stdlib_string_to_int_table_hex[curr_char - 97];
  151.  
  152.                 leftPart += curr_int * (long)__stdlib_string_to_double_table_hex[charNum2 - 1];
  153.                 --charNum2;
  154.             }
  155.         }
  156.     }
  157.     else
  158.     {
  159.         /* left part 1234. */
  160.         while (*str_ptr >= '0' && *str_ptr <= '9')
  161.         {
  162.             leftPart *= 10;
  163.             leftPart += *str_ptr - '0';
  164.             ++str_ptr;
  165.  
  166.             if (!*str_ptr)
  167.                 break;
  168.         }
  169.  
  170.         if (*str_ptr == 'e' || *str_ptr == 'E')
  171.         {
  172.             flags |= 0x4;
  173.             ++str_ptr;
  174.  
  175.             goto do_e;
  176.         }
  177.  
  178.         /* right part .5678 */
  179.         if (*str_ptr == decimal_point)
  180.         {
  181.             ++str_ptr;
  182.  
  183.             if (!*str_ptr)
  184.                 goto finish;
  185.  
  186.             while (*str_ptr >= '0' && *str_ptr <= '9')
  187.             {
  188.                 rightPart *= 10;
  189.                 rightPart += *str_ptr - '0';
  190.                 ++str_ptr;
  191.                 ++part_2_count;
  192.             }
  193.  
  194.             if (*str_ptr == 'e' || *str_ptr == 'E')
  195.             {
  196.                 flags |= 0x4;
  197.                 ++str_ptr;
  198.  
  199.                 goto do_e;
  200.             }
  201.         }
  202.     }
  203.  
  204. finish:;
  205.     result = leftPart + ((float)rightPart * __stdlib_string_to_double_table[part_2_count]);
  206.  
  207.     if (flags & 0x4)
  208.     {
  209.         double em = 1.0;
  210.  
  211.         for (int i = 0; i < e_right; ++i)
  212.         {
  213.             if (flags & 0x8) /* - */
  214.                 em *= 0.1;
  215.             else
  216.                 em *= 10.0;
  217.         }
  218.  
  219.         result = result * em;
  220.     }
  221.  
  222.     result = (flags & 0x1) ? -result : result;
  223.  
  224. end:;
  225.     if (endptr)
  226.         *endptr = (char*)str_ptr;
  227.  
  228.     return result;
  229.  
  230. do_e:;
  231.  
  232.     if (!*str_ptr)
  233.         goto finish;
  234.  
  235.     if (*str_ptr == '-')
  236.     {
  237.         flags |= 0x8;
  238.  
  239.         ++str_ptr;
  240.         if (!*str_ptr)
  241.             goto finish;
  242.     }
  243.     else if (*str_ptr == '+')
  244.     {
  245.         ++str_ptr;
  246.         if (!*str_ptr)
  247.             goto finish;
  248.     }
  249.  
  250.     while (*str_ptr >= '0' && *str_ptr <= '9')
  251.     {
  252.         e_right *= 10;
  253.         e_right += *str_ptr - '0';
  254.         ++str_ptr;
  255.     }
  256.     goto finish;
  257. }
  258.  
  259. int main()
  260. {
  261.     printf("Hello World %f\n", strtod("3.14159265359", 0));
  262.  
  263.     return 0;
  264. }
  265.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement