parseFloat.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. // Copyright Benoit Blanchon 2014-2017
  2. // MIT License
  3. //
  4. // Arduino JSON library
  5. // https://bblanchon.github.io/ArduinoJson/
  6. // If you like this project, please add a star!
  7. #include <gtest/gtest.h>
  8. #include <ArduinoJson/Polyfills/parseFloat.hpp>
  9. using namespace ArduinoJson::Polyfills;
  10. struct Polyfills_ParseFloat_Float_Tests : testing::Test {
  11. void check(const char* input, float expected) {
  12. float actual = parseFloat<float>(input);
  13. EXPECT_FLOAT_EQ(expected, actual) << input;
  14. }
  15. void checkNaN(const char* input) {
  16. float result = parseFloat<float>(input);
  17. EXPECT_TRUE(result != result) << input;
  18. }
  19. void checkInf(const char* input, bool negative) {
  20. float x = parseFloat<float>(input);
  21. if (negative)
  22. EXPECT_TRUE(x < 0) << input;
  23. else
  24. EXPECT_TRUE(x > 0) << input;
  25. EXPECT_TRUE(x == x && x * 2 == x) << input;
  26. }
  27. };
  28. #define TEST_FLOAT(X) TEST_F(Polyfills_ParseFloat_Float_Tests, X)
  29. struct Polyfills_ParseFloat_Double_Tests : testing::Test {
  30. void check(const char* input, double expected) {
  31. double actual = parseFloat<double>(input);
  32. EXPECT_DOUBLE_EQ(expected, actual) << input;
  33. }
  34. void checkNaN(const char* input) {
  35. double result = parseFloat<double>(input);
  36. EXPECT_TRUE(result != result) << input;
  37. }
  38. void checkInf(const char* input, bool negative) {
  39. double x = parseFloat<double>(input);
  40. if (negative)
  41. EXPECT_TRUE(x < 0) << input;
  42. else
  43. EXPECT_TRUE(x > 0) << input;
  44. EXPECT_TRUE(x == x && x * 2 == x) << input;
  45. }
  46. };
  47. #define TEST_DOUBLE(X) TEST_F(Polyfills_ParseFloat_Double_Tests, X)
  48. TEST_DOUBLE(Null) {
  49. check(NULL, 0);
  50. }
  51. TEST_FLOAT(Null) {
  52. check(NULL, 0);
  53. }
  54. TEST_DOUBLE(Short_NoExponent) {
  55. check("3.14", 3.14);
  56. check("-3.14", -3.14);
  57. check("+3.14", +3.14);
  58. }
  59. TEST_FLOAT(Float_Short_NoExponent) {
  60. check("3.14", 3.14f);
  61. check("-3.14", -3.14f);
  62. check("+3.14", +3.14f);
  63. }
  64. TEST_DOUBLE(Short_NoDot) {
  65. check("1E+308", 1E+308);
  66. check("-1E+308", -1E+308);
  67. check("+1E-308", +1E-308);
  68. check("+1e+308", +1e+308);
  69. check("-1e-308", -1e-308);
  70. }
  71. TEST_FLOAT(Short_NoDot) {
  72. check("1E+38", 1E+38f);
  73. check("-1E+38", -1E+38f);
  74. check("+1E-38", +1E-38f);
  75. check("+1e+38", +1e+38f);
  76. check("-1e-38", -1e-38f);
  77. }
  78. TEST_FLOAT(Max) {
  79. check("340.2823e+36", 3.402823e+38f);
  80. check("34.02823e+37", 3.402823e+38f);
  81. check("3.402823e+38", 3.402823e+38f);
  82. check("0.3402823e+39", 3.402823e+38f);
  83. check("00.3402823e+40", 3.402823e+38f);
  84. check("000.3402823e+41", 3.402823e+38f);
  85. }
  86. TEST_DOUBLE(Max) {
  87. check(".017976931348623147e+310", 1.7976931348623147e+308);
  88. check(".17976931348623147e+309", 1.7976931348623147e+308);
  89. check("1.7976931348623147e+308", 1.7976931348623147e+308);
  90. check("17.976931348623147e+307", 1.7976931348623147e+308);
  91. check("179.76931348623147e+306", 1.7976931348623147e+308);
  92. }
  93. TEST_DOUBLE(Min) {
  94. check(".022250738585072014e-306", 2.2250738585072014e-308);
  95. check(".22250738585072014e-307", 2.2250738585072014e-308);
  96. check("2.2250738585072014e-308", 2.2250738585072014e-308);
  97. check("22.250738585072014e-309", 2.2250738585072014e-308);
  98. check("222.50738585072014e-310", 2.2250738585072014e-308);
  99. }
  100. TEST_DOUBLE(VeryLong) {
  101. check("0.00000000000000000000000000000001", 1e-32);
  102. check("100000000000000000000000000000000.0", 1e+32);
  103. check("100000000000000000000000000000000.00000000000000000000000000000",
  104. 1e+32);
  105. }
  106. TEST_FLOAT(VeryLong) {
  107. check("0.00000000000000000000000000000001", 1e-32f);
  108. check("100000000000000000000000000000000.0", 1e+32f);
  109. check("100000000000000000000000000000000.00000000000000000000000000000",
  110. 1e+32f);
  111. }
  112. TEST_DOUBLE(MantissaTooLongToFit) {
  113. check("0.179769313486231571111111111111", 0.17976931348623157);
  114. check("17976931348623157.11111111111111", 17976931348623157.0);
  115. check("1797693.134862315711111111111111", 1797693.1348623157);
  116. check("-0.179769313486231571111111111111", -0.17976931348623157);
  117. check("-17976931348623157.11111111111111", -17976931348623157.0);
  118. check("-1797693.134862315711111111111111", -1797693.1348623157);
  119. }
  120. TEST_FLOAT(MantissaTooLongToFit) {
  121. check("0.340282346638528861111111111111", 0.34028234663852886f);
  122. check("34028234663852886.11111111111111", 34028234663852886.0f);
  123. check("34028234.66385288611111111111111", 34028234.663852886f);
  124. check("-0.340282346638528861111111111111", -0.34028234663852886f);
  125. check("-34028234663852886.11111111111111", -34028234663852886.0f);
  126. check("-34028234.66385288611111111111111", -34028234.663852886f);
  127. }
  128. TEST_DOUBLE(ExponentTooBig) {
  129. checkInf("1e309", false);
  130. checkInf("-1e309", true);
  131. checkInf("1e65535", false);
  132. check("1e-65535", 0.0);
  133. }
  134. TEST_FLOAT(ExponentTooBig) {
  135. checkInf("1e39", false);
  136. checkInf("-1e39", true);
  137. checkInf("1e255", false);
  138. check("1e-255", 0.0f);
  139. }
  140. TEST_DOUBLE(NaN) {
  141. checkNaN("NaN");
  142. checkNaN("nan");
  143. }
  144. TEST_FLOAT(NaN) {
  145. checkNaN("NaN");
  146. checkNaN("nan");
  147. }
  148. TEST_FLOAT(Infinity) {
  149. checkInf("Infinity", false);
  150. checkInf("+Infinity", false);
  151. checkInf("-Infinity", true);
  152. checkInf("inf", false);
  153. checkInf("+inf", false);
  154. checkInf("-inf", true);
  155. }