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
|
Field Type Null Key Default Extra
|
||||||
a decimal(21,2) NO 0.00
|
a decimal(21,2) NO 0.00
|
||||||
drop table t1,t2,t3;
|
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));
|
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').
|
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));
|
create table t1 (s1 float(1,2));
|
||||||
|
@ -178,7 +178,16 @@ show warnings;
|
|||||||
desc t3;
|
desc t3;
|
||||||
drop table t1,t2,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)
|
# bug #12694 (float(m,d) specifications)
|
||||||
|
@ -30,7 +30,8 @@
|
|||||||
#include "m_ctype.h"
|
#include "m_ctype.h"
|
||||||
|
|
||||||
#define MAX_DBL_EXP 308
|
#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[] = {
|
static double scaler10[] = {
|
||||||
1.0, 1e10, 1e20, 1e30, 1e40, 1e50, 1e60, 1e70, 1e80, 1e90
|
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;
|
double result= 0.0;
|
||||||
uint negative= 0, ndigits, dec_digits= 0, neg_exp= 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;
|
const char *old_str, *end= *end_ptr, *start_of_number;
|
||||||
char next_char;
|
char next_char;
|
||||||
my_bool overflow=0;
|
my_bool overflow=0;
|
||||||
|
double scaler= 1.0;
|
||||||
|
|
||||||
*error= 0;
|
*error= 0;
|
||||||
if (str >= end)
|
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')
|
while ((next_char= *str) >= '0' && next_char <= '9')
|
||||||
{
|
{
|
||||||
result= result*10.0 + (next_char - '0');
|
result= result*10.0 + (next_char - '0');
|
||||||
|
scaler= scaler*10.0;
|
||||||
if (++str == end)
|
if (++str == end)
|
||||||
{
|
{
|
||||||
next_char= 0; /* Found end of string */
|
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');
|
result= result*10.0 + (next_char - '0');
|
||||||
digits_after_dec_point++;
|
digits_after_dec_point++;
|
||||||
|
scaler= scaler*10.0;
|
||||||
if (++str == end)
|
if (++str == end)
|
||||||
{
|
{
|
||||||
next_char= 0;
|
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));
|
} while (str < end && my_isdigit(&my_charset_latin1, *str));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((exp= (neg_exp ? exp + digits_after_dec_point :
|
tmp_exp= neg_exp ? exp + digits_after_dec_point : 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)
|
if (exp < 0)
|
||||||
{
|
{
|
||||||
exp= -exp;
|
exp= -exp;
|
||||||
neg_exp= 1; /* neg_exp was 0 before */
|
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)
|
while (exp >= 100)
|
||||||
{
|
{
|
||||||
scaler*= 1.0e100;
|
result= neg_exp ? result/1.0e100 : result*1.0e100;
|
||||||
exp-= 100;
|
exp-= 100;
|
||||||
}
|
}
|
||||||
scaler*= scaler10[exp/10]*scaler1[exp%10];
|
scaler= scaler10[exp/10]*scaler1[exp%10];
|
||||||
if (neg_exp)
|
if (neg_exp)
|
||||||
result/= scaler;
|
result/= scaler;
|
||||||
else
|
else
|
||||||
|
Reference in New Issue
Block a user