Advertisement
Guest User

Untitled

a guest
Nov 30th, 2020
161
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.81 KB | None | 0 0
  1. #include <cstdio>
  2. #include <cstdlib>
  3. // #include <sstream>
  4. #include <string>
  5. // #include <string.h>
  6. #include <iostream>
  7. #include <functional>
  8. #include <iomanip>
  9. #include <algorithm>
  10. #include <cmath>
  11.  
  12. #undef _CRT_DEPRECATE_TEXT
  13. #undef _CRT_NONSTDC_DEPRECATE
  14. #undef _CRT_INSECURE_DEPRECATE
  15.  
  16. using uint32_t = unsigned int;
  17. using u32 = uint32_t;
  18.  
  19. char *ecvt(double x, int n, int *dp, int *sign)
  20. {
  21.     static char buf[16];
  22.     char tmp[32];
  23.     int i, j;
  24.  
  25.     if (n - 1U > 15)
  26.         n = 15;
  27.  
  28.     sprintf(tmp, "%.*e", n - 1, x);
  29.     i = *sign = (tmp[0] == '-');
  30.  
  31.     for (j = 0; tmp[i] != 'e'; j += (tmp[i++] != '.'))
  32.         buf[j] = tmp[i];
  33.  
  34.     buf[j] = 0;
  35.     *dp = atoi(tmp + i + 1) + 1;
  36.     return buf;
  37. }
  38.  
  39. // char *ecvt2(double x, int n, int *dp, int *sign)
  40. // {
  41. //     char tmp[32];
  42. //     n = std::min(n, 15);
  43. //     std::sprintf(tmp, "%.*e", n - 1, x);
  44. //     std::string doubleString = std::string(tmp);
  45. //     *sign = doubleString[0] == '-';
  46. //     doubleString.erase(std::remove(doubleString.begin(), doubleString.end(), 'e'), doubleString.end());
  47. //     doubleString.erase(std::remove(doubleString.begin(), doubleString.end(), '-'), doubleString.end());
  48. //     doubleString.erase(std::remove(doubleString.begin(), doubleString.end(), '.'), doubleString.end());
  49. //     *dp =doubleString.length();
  50. //     return &doubleString[0];
  51. // }
  52.  
  53.  
  54.  
  55. char* ecvt3(double x, int n, int *dp, int *sign)
  56. {
  57.     char tmp[32];
  58.     n = std::min(n, 15);
  59.     std::sprintf(tmp, "%.*e", n - 1, x);
  60.     std::string str(tmp);
  61.     *sign = str[0] == '-';
  62.     if (str == "inf" || str == "-inf")
  63.     {
  64.         *dp = 1;
  65.         return "1#INF";
  66.     }
  67.     else if ((str == "nan" || str == "-nan"))
  68.     {
  69.         *dp = 1;
  70.         return "1#QNAN";
  71.     }
  72.     else if ((str == "-nan(ind)" || str == "-nan(ind)"))
  73.     {
  74.         *dp = 1;
  75.         return "1#IND";
  76.     }
  77.     else
  78.     {
  79.         *dp = std::atoi(tmp + str.find('e') + 1) + 1;
  80.     }
  81.  
  82.     int index = 0;
  83.     str.erase(
  84.         std::remove_if(
  85.             str.begin(),
  86.             str.end(),
  87.             [&index, n](unsigned char x){
  88.                 bool ShouldRemove = index > n || x == '+' || x == 'e' || x == '-' || x == '.';
  89.                 if(!ShouldRemove)
  90.                     ++index;
  91.                 return ShouldRemove;
  92.             }
  93.     ));
  94.  
  95.     char *cstr = new char[str.length() + 1];
  96.     strcpy(cstr, str.c_str());
  97.     return cstr;
  98. }
  99.  
  100.  
  101.  
  102.  
  103.  
  104. namespace std
  105. {
  106.     inline double round(double v, int p)
  107.     {
  108.         return std::round(v * std::pow(10, p)) / std::pow(10, p);
  109.     }
  110. } // namespace std
  111.  
  112. void FloatToString3(double f, char* sz)
  113. {
  114.     std::string str = std::to_string(3.1415926);
  115.     char *cstr = new char[str.length() + 1];
  116.     strcpy(cstr, str.c_str());
  117.     sz = cstr;
  118. }
  119.  
  120. void FloatToString2(double f, char* sz)
  121. {
  122.     static const int digitCount = 6;
  123.     bool isNegative = f < 0.0f;
  124.     f = std::round(f, digitCount);
  125.     std::snprintf(sz, 128, "%c%lf", isNegative ? '-' : 0, f);
  126. }
  127.  
  128. void FloatToString(float f, char* sz, std::function<char*(double, int, int*, int*)> function)
  129. {
  130.     char* buffer = sz + 1;
  131.     static const int digitCount = 6;
  132.     int decimal, sign;
  133.     // ecvt rounds the string for us: http://www.datafocus.com/docs/man3/ecvt.3.asp
  134.     char* end = function(f, digitCount, &decimal, &sign);
  135.     if (sign != 0) (*buffer++) = '-';
  136.     int count = digitCount;
  137.     if (decimal > digitCount)
  138.     {
  139.         // We use the scientific notation: P.MeX
  140.         (*buffer++) = (*end++); // P is one character.
  141.         (*buffer++) = '.';
  142.  
  143.         // Mantissa (cleaned for zeroes)
  144.         for (--count; count > 0; --count) if (end[count - 1] != '0') break;
  145.         for (int i = 0; i < count; ++i) (*buffer++) = (*end++);
  146.         if (buffer[-1] == '.') --buffer;
  147.  
  148.         // Exponent
  149.         (*buffer++) = 'e';
  150.         u32 exponent = decimal - 1; // X
  151.         if (exponent >= 10) (*buffer++) = (char) ('0' + (exponent / 10));
  152.         (*buffer++) = (char) ('0' + (exponent % 10));
  153.         (*buffer) = 0;
  154.         return;
  155.     }
  156.     else if (decimal > 0)
  157.     {
  158.         // Simple number: A.B
  159.         for (int i = 0; i < decimal; ++i) (*buffer++) = (*end++);
  160.         if (decimal < digitCount) (*buffer++) = '.';
  161.         count = digitCount - decimal;
  162.     }
  163.     else if (decimal < -digitCount)
  164.     {
  165.         // What case is this?
  166.         decimal = count = 0;
  167.     }
  168.     else if (decimal < 0 || (decimal == 0 && *end != '0'))
  169.     {
  170.         // Tiny number: 0.Me-X
  171.         (*buffer++) = '0'; (*buffer++) = '.';
  172.         for (int i = 0; i < -decimal; ++i) (*buffer++) = '0';
  173.         count = digitCount + decimal;
  174.     }
  175.     for (; count > 0; --count) if (end[count - 1] != '0') break;
  176.     for (int i = 0; i < count; ++i) (*buffer++) = (*end++);
  177.     if (decimal == 0 && count == 0) (*buffer++) = '0';
  178.     if (buffer[-1] == '.') --buffer;
  179.     (*buffer) = 0;
  180. }
  181.  
  182. void ecvt_wrapper(float source)
  183. {
  184.     // std::cout << "------------------"<< source << "------------------------------" << std::endl;
  185.     // int decimal, sign;
  186.     // char *buffer;
  187.     // int precision = 10;
  188.     // buffer = ecvt(source, precision, &decimal, &sign);
  189.     // std::cout << "Musl implem: " << buffer << " sign: " << sign << " decimal: " << decimal << std::endl;
  190.     // buffer = ecvt2(source, precision, &decimal, &sign);
  191.     // std::cout << "New implem: " << buffer << " sign: " << sign << " decimal: " << decimal << std::endl;
  192.     // buffer = _ecvt(source, precision, &decimal, &sign);
  193.     // std::cout << "Native implem: " << buffer << " sign: " << sign << " decimal: " << decimal << std::endl;
  194.  
  195.  
  196.  
  197.     std::cout << "----------------------"<<source<<"--------------------------" << std::endl;
  198.  
  199.     char sz[128];
  200.     float so = static_cast<float>(source);
  201.     // FloatToString(so, sz,ecvt2);
  202.     // std::cout << "New implem: " << sz + 1 << std::endl;
  203.     FloatToString(so, sz,ecvt3);
  204.     std::cout << "New implem++: " << sz + 1 << std::endl;
  205.     FloatToString(so, sz,_ecvt);
  206.     std::cout << "Native implem: " << sz + 1 << std::endl;
  207.     // FloatToString(so, sz,ecvt);
  208.     // std::cout << "MUSL implem: " << sz + 1 << std::endl;
  209.     FloatToString2(so, sz);
  210.     std::cout << "SNPRINTF implem: " << sz + 1 << std::endl;
  211.     FloatToString3(so, sz);
  212.     std::cout << "to_string: " << sz + 1 << std::endl;
  213. }
  214.  
  215.  
  216.  
  217.  
  218. int main()
  219. {
  220.     ecvt_wrapper(-3.1415926535);
  221.     ecvt_wrapper(-3.1415926535);
  222.     ecvt_wrapper(-12415.1415926535);
  223.     ecvt_wrapper(+12415.1415926535);
  224.     ecvt_wrapper(+12415.12034578);
  225.     ecvt_wrapper(+12415.120341111118);
  226.     ecvt_wrapper(+0.120341111118);
  227.     ecvt_wrapper(-0.120341111118);
  228.     ecvt_wrapper(0.5);
  229.     ecvt_wrapper(0.0);
  230.     ecvt_wrapper(4e5);
  231.     ecvt_wrapper(4e-5);
  232.     ecvt_wrapper(-4e-5);
  233.     ecvt_wrapper(4e5);
  234.     ecvt_wrapper(4e25);
  235.     ecvt_wrapper(-4e25);
  236.     ecvt_wrapper(4e-25);
  237.     ecvt_wrapper(-4e-25);
  238.  
  239.     ecvt_wrapper(std::numeric_limits<float>::max());
  240.     ecvt_wrapper(std::numeric_limits<float>::min());
  241.     ecvt_wrapper(std::numeric_limits<double>::max());
  242.     ecvt_wrapper(std::numeric_limits<double>::min());
  243.  
  244.     ecvt_wrapper(-std::numeric_limits<float>::max());
  245.     ecvt_wrapper(-std::numeric_limits<float>::min());
  246.     ecvt_wrapper(-std::numeric_limits<double>::max());
  247.     ecvt_wrapper(-std::numeric_limits<double>::min());
  248.  
  249.     ecvt_wrapper(std::numeric_limits<float>::quiet_NaN());
  250.     ecvt_wrapper(-std::numeric_limits<float>::quiet_NaN());
  251.     ecvt_wrapper(std::numeric_limits<float>::signaling_NaN());
  252.     ecvt_wrapper(-std::numeric_limits<float>::signaling_NaN());
  253.     ecvt_wrapper(std::numeric_limits<double>::quiet_NaN());
  254.     ecvt_wrapper(-std::numeric_limits<double>::quiet_NaN());
  255.     ecvt_wrapper(std::numeric_limits<double>::signaling_NaN());
  256.     ecvt_wrapper(-std::numeric_limits<double>::signaling_NaN());
  257.     ecvt_wrapper(1);
  258.     ecvt_wrapper(std::numeric_limits<float>::infinity());
  259.     ecvt_wrapper(std::numeric_limits<double>::infinity());
  260.     ecvt_wrapper(-std::numeric_limits<float>::infinity());
  261.     ecvt_wrapper(-std::numeric_limits<double>::infinity());
  262.     return 0;
  263. }
  264.  
  265.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement