strutil: Fix sr_parse_rational for integral parts between -0 and -1
Values like '-0.1' would be parsed as being positive, as the integral type does not discern +0 and -0. Also allow values without leading integral value, to match behaviour of strtod/sr_atof.
This commit is contained in:
parent
f05600f4be
commit
41c47f2c6a
|
@ -233,13 +233,19 @@ SR_API int sr_parse_rational(const char *str, struct sr_rational *ret)
|
||||||
int64_t denominator = 1;
|
int64_t denominator = 1;
|
||||||
int32_t fractional_len = 0;
|
int32_t fractional_len = 0;
|
||||||
int32_t exponent = 0;
|
int32_t exponent = 0;
|
||||||
|
int is_negative = 0;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
integral = g_ascii_strtoll(str, &endptr, 10);
|
integral = g_ascii_strtoll(str, &endptr, 10);
|
||||||
|
|
||||||
if (errno)
|
if (str == endptr && (str[0] == '-' || str[0] == '+') && str[1] == '.')
|
||||||
|
endptr += 1;
|
||||||
|
else if (errno)
|
||||||
return SR_ERR;
|
return SR_ERR;
|
||||||
|
|
||||||
|
if (integral < 0 || str[0] == '-')
|
||||||
|
is_negative = 1;
|
||||||
|
|
||||||
if (*endptr == '.') {
|
if (*endptr == '.') {
|
||||||
const char* start = endptr + 1;
|
const char* start = endptr + 1;
|
||||||
fractional = g_ascii_strtoll(start, &endptr, 10);
|
fractional = g_ascii_strtoll(start, &endptr, 10);
|
||||||
|
@ -261,7 +267,7 @@ SR_API int sr_parse_rational(const char *str, struct sr_rational *ret)
|
||||||
integral *= 10;
|
integral *= 10;
|
||||||
exponent -= fractional_len;
|
exponent -= fractional_len;
|
||||||
|
|
||||||
if (integral >= 0)
|
if (!is_negative)
|
||||||
integral += fractional;
|
integral += fractional;
|
||||||
else
|
else
|
||||||
integral -= fractional;
|
integral -= fractional;
|
||||||
|
|
|
@ -255,6 +255,11 @@ START_TEST(test_fractional)
|
||||||
test_rational("12.34", (struct sr_rational){1234, 100});
|
test_rational("12.34", (struct sr_rational){1234, 100});
|
||||||
test_rational("-12.34", (struct sr_rational){-1234, 100});
|
test_rational("-12.34", (struct sr_rational){-1234, 100});
|
||||||
test_rational("10.00", (struct sr_rational){1000, 100});
|
test_rational("10.00", (struct sr_rational){1000, 100});
|
||||||
|
test_rational(".1", (struct sr_rational){1, 10});
|
||||||
|
test_rational("+0.1", (struct sr_rational){1, 10});
|
||||||
|
test_rational("+.1", (struct sr_rational){1, 10});
|
||||||
|
test_rational("-0.1", (struct sr_rational){-1, 10});
|
||||||
|
test_rational("-.1", (struct sr_rational){-1, 10});
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
@ -270,6 +275,11 @@ START_TEST(test_exponent)
|
||||||
test_rational("0.001e3", (struct sr_rational){1, 1});
|
test_rational("0.001e3", (struct sr_rational){1, 1});
|
||||||
test_rational("0.001e0", (struct sr_rational){1, 1000});
|
test_rational("0.001e0", (struct sr_rational){1, 1000});
|
||||||
test_rational("0.001e-3", (struct sr_rational){1, 1000000});
|
test_rational("0.001e-3", (struct sr_rational){1, 1000000});
|
||||||
|
test_rational("43.737E-3", (struct sr_rational){43737, 1000000});
|
||||||
|
test_rational("-0.1e-2", (struct sr_rational){-1, 1000});
|
||||||
|
test_rational("-.1e-2", (struct sr_rational){-1, 1000});
|
||||||
|
test_rational("-.0e-2", (struct sr_rational){0, 1000});
|
||||||
|
test_rational("+.0e-2", (struct sr_rational){0, 1000});
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue