json-tutorial icon indicating copy to clipboard operation
json-tutorial copied to clipboard

tutorial02_answer中关于数字过大的处理的问题。

Open shuaitq opened this issue 8 years ago • 8 comments

  1. errno == ERANGE
  2. v->n == HUGE_VAL 这两种方法都是看是否数字过大,有何区别,为何要同时使用两种方法。

我测试了v->n == HUGE_VAL,光用着一种方法就能够通过测试。

shuaitq avatar Dec 01 '16 15:12 shuaitq

可以把你的测试集贴上来么?

feiwofeifeixiaowo avatar Dec 02 '16 01:12 feiwofeifeixiaowo

TEST_NUMBER(5.0E-324,"5e-324"); /*Min subnormal positive double*/ TEST_NUMBER(1.7976931348623157E308,"1.7976931348623157E308"); /*Max Double*/ TEST_NUMBER(1.0000000000000002, "1.0000000000000002"); /* the smallest number > 1 */ TEST_NUMBER( 4.9406564584124654e-324, "4.9406564584124654e-324"); /* minimum denormal */ TEST_NUMBER(-4.9406564584124654e-324, "-4.9406564584124654e-324"); TEST_NUMBER( 2.2250738585072009e-308, "2.2250738585072009e-308"); /* Max subnormal double */ TEST_NUMBER(-2.2250738585072009e-308, "-2.2250738585072009e-308"); TEST_NUMBER( 2.2250738585072014e-308, "2.2250738585072014e-308"); /* Min normal positive double */ TEST_NUMBER(-2.2250738585072014e-308, "-2.2250738585072014e-308"); TEST_NUMBER( 1.7976931348623157e+308, "1.7976931348623157e+308"); /* Max double */ TEST_NUMBER(-1.7976931348623157e+308, "-1.7976931348623157e+308");

前面两个是在维基百科找的,后面是tutorial02_answer中的。

if(v->n==HUGE_VAL){ return LEPT_PARSE_NUMBER_TOO_BIG; }

使用这样的写法都能够通过。

shuaitq avatar Dec 02 '16 01:12 shuaitq

应该是可以的

miloyip avatar Dec 04 '16 03:12 miloyip

那请问两种方法有何区别?为何要同时使用?

shuaitq avatar Dec 05 '16 03:12 shuaitq

经过测试得出这样的结论: 上溢出跟下溢出,都是会使errno==ERANGE 后面的v->n == HUGE_VAL || v->n == HUGE_VAL 主要是确定这是上溢出

至于为什么判定负号 楼主加个 TEST_ERROR(LEPT_PARSE_NUMBER_TOO_BIG, "-1e309");就知道为什么了

JosanSun avatar Feb 13 '17 12:02 JosanSun

我测试了一下。 例如在解析5e-324之类的数值的时候,errno==ERANGE,但是val解析出来没有溢出。 如果val==+/-HUGE_VAL,那么errno一定会被设置为ERANGE。 所以应该只需要判断val是否为+/-HUGE_VAL就行了

Yuan-Hang avatar Apr 16 '17 10:04 Yuan-Hang

If the correct value would cause overflow, plus or minus HUGE_VAL (HUGE_VALF, HUGE_VALL) is returned (according to the sign of the value), and ERANGE is stored in errno. If the correct value would cause underflow, zero is returned and ERANGE is stored in errno.

上面的是man strtod原话,如果只是检查overflow是可以只检查val是否为+/-HUGE_VAL

zyc737347123 avatar Nov 11 '17 06:11 zyc737347123

测试用例里有一个就是underflow : TEST_NUMBER(0.0, "1e-10000"); /* must underflow */ 就是errno==ERANGE, return val 是0的情况。

zyc737347123 avatar Nov 11 '17 07:11 zyc737347123