mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merge polly.local:/tmp/22129/bug22129/my50-bug22129
into polly.local:/home/kaa/src/maint/m50-maint--07OGt
This commit is contained in:
@ -262,6 +262,13 @@ desc t3;
|
||||
Field Type Null Key Default Extra
|
||||
a decimal(21,2) NO 0.00
|
||||
drop table t1,t2,t3;
|
||||
select 1e-308, 1.00000001e-300, 100000000e-300;
|
||||
1e-308 1.00000001e-300 100000000e-300
|
||||
0 1.00000001e-300 1e-292
|
||||
select 10e307;
|
||||
10e307
|
||||
1e+308
|
||||
End of 4.1 tests
|
||||
create table t1 (s1 float(0,2));
|
||||
ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 's1').
|
||||
create table t1 (s1 float(1,2));
|
||||
|
@ -178,7 +178,16 @@ show warnings;
|
||||
desc t3;
|
||||
drop table t1,t2,t3;
|
||||
|
||||
# End of 4.1 tests
|
||||
#
|
||||
# Bug #22129: A small double precision number becomes zero
|
||||
#
|
||||
# check if underflows are detected correctly
|
||||
select 1e-308, 1.00000001e-300, 100000000e-300;
|
||||
|
||||
# check if overflows are detected correctly
|
||||
select 10e307;
|
||||
|
||||
--echo End of 4.1 tests
|
||||
|
||||
#
|
||||
# bug #12694 (float(m,d) specifications)
|
||||
|
@ -30,7 +30,8 @@
|
||||
#include "m_ctype.h"
|
||||
|
||||
#define MAX_DBL_EXP 308
|
||||
#define MAX_RESULT_FOR_MAX_EXP 1.79769313486232
|
||||
#define MAX_RESULT_FOR_MAX_EXP 1.7976931348623157
|
||||
#define MIN_RESULT_FOR_MIN_EXP 2.225073858507202
|
||||
static double scaler10[] = {
|
||||
1.0, 1e10, 1e20, 1e30, 1e40, 1e50, 1e60, 1e70, 1e80, 1e90
|
||||
};
|
||||
@ -57,10 +58,11 @@ double my_strtod(const char *str, char **end_ptr, int *error)
|
||||
{
|
||||
double result= 0.0;
|
||||
uint negative= 0, ndigits, dec_digits= 0, neg_exp= 0;
|
||||
int exp= 0, digits_after_dec_point= 0;
|
||||
int exp= 0, digits_after_dec_point= 0, tmp_exp;
|
||||
const char *old_str, *end= *end_ptr, *start_of_number;
|
||||
char next_char;
|
||||
my_bool overflow=0;
|
||||
double scaler= 1.0;
|
||||
|
||||
*error= 0;
|
||||
if (str >= end)
|
||||
@ -91,6 +93,7 @@ double my_strtod(const char *str, char **end_ptr, int *error)
|
||||
while ((next_char= *str) >= '0' && next_char <= '9')
|
||||
{
|
||||
result= result*10.0 + (next_char - '0');
|
||||
scaler= scaler*10.0;
|
||||
if (++str == end)
|
||||
{
|
||||
next_char= 0; /* Found end of string */
|
||||
@ -114,6 +117,7 @@ double my_strtod(const char *str, char **end_ptr, int *error)
|
||||
{
|
||||
result= result*10.0 + (next_char - '0');
|
||||
digits_after_dec_point++;
|
||||
scaler= scaler*10.0;
|
||||
if (++str == end)
|
||||
{
|
||||
next_char= 0;
|
||||
@ -144,39 +148,54 @@ double my_strtod(const char *str, char **end_ptr, int *error)
|
||||
} while (str < end && my_isdigit(&my_charset_latin1, *str));
|
||||
}
|
||||
}
|
||||
if ((exp= (neg_exp ? exp + digits_after_dec_point :
|
||||
exp - digits_after_dec_point)))
|
||||
tmp_exp= neg_exp ? exp + digits_after_dec_point : exp - digits_after_dec_point;
|
||||
if (tmp_exp)
|
||||
{
|
||||
double scaler;
|
||||
int order;
|
||||
/*
|
||||
Check for underflow/overflow.
|
||||
order is such an integer number that f = C * 10 ^ order,
|
||||
where f is the resulting floating point number and 1 <= C < 10.
|
||||
Here we compute the modulus
|
||||
*/
|
||||
order= exp + (neg_exp ? -1 : 1) * (ndigits - 1);
|
||||
if (order < 0)
|
||||
order= -order;
|
||||
if (order >= MAX_DBL_EXP && result)
|
||||
{
|
||||
double c;
|
||||
/* Compute modulus of C (see comment above) */
|
||||
c= result / scaler * 10.0;
|
||||
if (neg_exp)
|
||||
{
|
||||
if (order > MAX_DBL_EXP || c < MIN_RESULT_FOR_MIN_EXP)
|
||||
{
|
||||
result= 0.0;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (order > MAX_DBL_EXP || c > MAX_RESULT_FOR_MAX_EXP)
|
||||
{
|
||||
overflow= 1;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exp= tmp_exp;
|
||||
if (exp < 0)
|
||||
{
|
||||
exp= -exp;
|
||||
neg_exp= 1; /* neg_exp was 0 before */
|
||||
}
|
||||
if (exp + ndigits >= MAX_DBL_EXP + 1 && result)
|
||||
{
|
||||
/*
|
||||
This is not 100 % as we actually will give an owerflow for
|
||||
17E307 but not for 1.7E308 but lets cut some corners to make life
|
||||
simpler
|
||||
*/
|
||||
if (exp + ndigits > MAX_DBL_EXP + 1 ||
|
||||
result >= MAX_RESULT_FOR_MAX_EXP)
|
||||
{
|
||||
if (neg_exp)
|
||||
result= 0.0;
|
||||
else
|
||||
overflow= 1;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
scaler= 1.0;
|
||||
while (exp >= 100)
|
||||
{
|
||||
scaler*= 1.0e100;
|
||||
result= neg_exp ? result/1.0e100 : result*1.0e100;
|
||||
exp-= 100;
|
||||
}
|
||||
scaler*= scaler10[exp/10]*scaler1[exp%10];
|
||||
scaler= scaler10[exp/10]*scaler1[exp%10];
|
||||
if (neg_exp)
|
||||
result/= scaler;
|
||||
else
|
||||
|
Reference in New Issue
Block a user