• 自行实现字符串转浮点数函数atof()


    【重复造轮子的原因】

    尽管atof是标准C中自带的函数,用于将字符串转为浮点数,但是在某些环境下有可能没法使用的(例如CUDA环境中,没有atof函数,但是math.h可以使用),因此自行实现。

    【通过的测试用例】

    【实现的代码】

    1. #include
    2. #include
    3. #include
    4. //自己实现字符串转浮点数,可用于某些自带atof()使用不了的环境(例如CUDA的核函数中)
    5. double my_atof(const char *str);
    6. //两个double是否相同(模糊比较)
    7. bool isFuzzyEqual(double a, double b)
    8. {
    9. double min = fmin(fabs(a), fabs(b));
    10. double dif = fabs(a - b);
    11. return (dif * 1.0E12 <= min);
    12. }
    13. int main()
    14. {
    15. assert(isFuzzyEqual(my_atof("123.456"), 123.456));
    16. assert(isFuzzyEqual(my_atof("0123.456"), 123.456));
    17. assert(isFuzzyEqual(my_atof("+123.456"), 123.456));
    18. assert(isFuzzyEqual(my_atof("123.456 abc"), 123.456));
    19. assert(isFuzzyEqual(my_atof(" 123.456 78"), 123.456));
    20. assert(isFuzzyEqual(my_atof("1.23456E2"), 123.456));
    21. assert(isFuzzyEqual(my_atof("1.23456e2"), 123.456));
    22. assert(isFuzzyEqual(my_atof("12345.6E-2"), 123.456));
    23. assert(isFuzzyEqual(my_atof("123456E-3"), 123.456));
    24. assert(isFuzzyEqual(my_atof("-123.456"), -123.456));
    25. assert(isFuzzyEqual(my_atof("-1.23456E2"), -123.456));
    26. assert(isFuzzyEqual(my_atof("0.678"), 0.678));
    27. assert(isFuzzyEqual(my_atof(".678"), 0.678));
    28. assert(isFuzzyEqual(my_atof("-.678"), -0.678));
    29. assert(isFuzzyEqual(my_atof("2E-3"), 0.002));
    30. assert(isFuzzyEqual(my_atof("-2E-3"), -0.002));
    31. assert(isFuzzyEqual(my_atof("-2.0E-3"), -0.002));
    32. return 0;
    33. }
    34. double my_atof(const char *str)
    35. {
    36. if (str == NULL)
    37. {
    38. assert(false);
    39. return 0.0;
    40. }
    41. int sign = 1; //正负符号
    42. int sign_zhi = 1; //指数正负符号
    43. double zheng = 0.0; //整数部分
    44. double xiao = 0.0; //小数部分
    45. int zhi = 0; //指数部分
    46. bool hasS = false; //是否有正负符号
    47. bool hasPoint = false; //是否有小数点
    48. bool hasE = false; //是否有指数的符号E/e
    49. bool hasES = false; //是否有指数的正负符号
    50. int xiao_len = 0; //小数位长度
    51. int i = 0;
    52. const char *ps = str;
    53. //忽略前置空格和制表符
    54. while (ps[i] == ' ' || ps[i] == '\t') ++i;
    55. if (ps[i] == '-')
    56. {
    57. hasS = true;
    58. sign = -1;
    59. i++;
    60. }
    61. else if (ps[i] == '+')
    62. {
    63. hasS = true;
    64. sign = 1;
    65. i++;
    66. }
    67. while (true)
    68. {
    69. //中途遇到结束字符和空字符则后续被忽略
    70. if (ps[i] == '\0' || ps[i] == ' ' || ps[i] == '\t') break;
    71. if ((ps[i] >= '0' && ps[i] <= '9') || ps[i] == '-' || ps[i] == '+')
    72. {
    73. if (hasE)
    74. {
    75. if (ps[i] == '-' || ps[i] == '+')
    76. {
    77. if (hasES)
    78. {
    79. assert(false); //错误格式或不识别的格式
    80. return 0.0;
    81. }
    82. hasES = true;
    83. sign_zhi = (ps[i] == '-') ? -1 : 1;
    84. }
    85. else
    86. {
    87. zhi = zhi * 10 + (ps[i]-'0');
    88. }
    89. }
    90. else if (hasPoint)
    91. {
    92. if (ps[i] >= '0' && ps[i] <= '9')
    93. {
    94. xiao_len++;
    95. xiao += (ps[i] - '0') * pow(10.0, -xiao_len);
    96. }
    97. else
    98. {
    99. assert(false); //错误格式或不识别的格式
    100. return 0.0;
    101. }
    102. }
    103. else
    104. {
    105. if (ps[i] == '-' || ps[i] == '+')
    106. {
    107. if (hasS)
    108. {
    109. assert(false); //错误格式或不识别的格式
    110. return 0.0;
    111. }
    112. hasE = true;
    113. sign = (ps[i] == '-') ? -1 : 1;
    114. }
    115. else
    116. {
    117. zheng = zheng * 10 + (ps[i] - '0');
    118. }
    119. }
    120. i++;
    121. continue;
    122. } //[+-0^9]
    123. else if (ps[i] == '.')
    124. {
    125. if (hasPoint)
    126. {
    127. assert(false); //错误格式或不识别的格式
    128. return 0.0;
    129. }
    130. hasPoint = true;
    131. i++;
    132. continue;
    133. }
    134. else if (ps[i] == 'E' || ps[i] == 'e')
    135. {
    136. if (hasE)
    137. {
    138. assert(false); //错误格式或不识别的格式
    139. return 0.0;
    140. }
    141. hasE = true;
    142. ++i;
    143. continue;
    144. }
    145. } // end of while
    146. zhi *= sign_zhi;
    147. double value = sign * (zheng + xiao) * pow(10, zhi);
    148. //TEST
    149. printf("TEST my_atof: %s --> %.14f\n", str, value);
    150. return value;
    151. }

  • 相关阅读:
    线程池的使用(结合Future/Callable使用)
    Scrapy-reids-概念
    Activity
    Python进阶系列 - 18讲 伟大的*号
    ZYNQ之HLS学习----开篇实验
    企业架构LNMP学习笔记9
    算法----二维区域和检索 - 矩阵不可变(Kotlin)
    Qt项目天气预报(1) - ui界面搭建
    PMP 11.27 考试倒计时3天!
    数组06-滑动窗口
  • 原文地址:https://blog.csdn.net/piaopiaolanghua/article/details/132750114