Commit 1ac607be authored by dkatz@damien-katzs-computer.local's avatar dkatz@damien-katzs-computer.local

Merge damien-katzs-computer.local:/Users/dkatz/mysql50

into  damien-katzs-computer.local:/Users/dkatz/50_dump
parents 4a7cdfc0 cc5d3d2e
...@@ -105,6 +105,10 @@ extern char *stpcpy(char *, const char *); /* For AIX with gcc 2.95.3 */ ...@@ -105,6 +105,10 @@ extern char *stpcpy(char *, const char *); /* For AIX with gcc 2.95.3 */
extern char NEAR _dig_vec_upper[]; extern char NEAR _dig_vec_upper[];
extern char NEAR _dig_vec_lower[]; extern char NEAR _dig_vec_lower[];
/* Defined in strtod.c */
extern const double log_10[309];
extern const double log_01[309];
#ifdef BAD_STRING_COMPILER #ifdef BAD_STRING_COMPILER
#define strmov(A,B) (memccpy(A,B,0,INT_MAX)-1) #define strmov(A,B) (memccpy(A,B,0,INT_MAX)-1)
#else #else
......
...@@ -3607,6 +3607,9 @@ sub do_before_start_master ($) { ...@@ -3607,6 +3607,9 @@ sub do_before_start_master ($) {
# FIXME what about second master..... # FIXME what about second master.....
# Don't delete anything if starting dirty
return if ($opt_start_dirty);
foreach my $bin ( glob("$opt_vardir/log/master*-bin*") ) foreach my $bin ( glob("$opt_vardir/log/master*-bin*") )
{ {
unlink($bin); unlink($bin);
...@@ -3638,6 +3641,9 @@ sub do_before_start_slave ($) { ...@@ -3638,6 +3641,9 @@ sub do_before_start_slave ($) {
my $tname= $tinfo->{'name'}; my $tname= $tinfo->{'name'};
my $init_script= $tinfo->{'master_sh'}; my $init_script= $tinfo->{'master_sh'};
# Don't delete anything if starting dirty
return if ($opt_start_dirty);
foreach my $bin ( glob("$opt_vardir/log/slave*-bin*") ) foreach my $bin ( glob("$opt_vardir/log/slave*-bin*") )
{ {
unlink($bin); unlink($bin);
......
...@@ -344,3 +344,36 @@ create table t1 (s1 float(0,2)); ...@@ -344,3 +344,36 @@ 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));
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 (f1 double(200, 0));
insert into t1 values (1e199), (-1e199);
insert into t1 values (1e200), (-1e200);
insert into t1 values (2e200), (-2e200);
Warnings:
Warning 1264 Out of range value adjusted for column 'f1' at row 1
Warning 1264 Out of range value adjusted for column 'f1' at row 2
select f1 + 0e0 from t1;
f1 + 0e0
1e+199
-1e+199
1e+200
-1e+200
1e+200
-1e+200
drop table t1;
create table t1 (f1 float(30, 0));
insert into t1 values (1e29), (-1e29);
insert into t1 values (1e30), (-1e30);
insert into t1 values (2e30), (-2e30);
Warnings:
Warning 1264 Out of range value adjusted for column 'f1' at row 1
Warning 1264 Out of range value adjusted for column 'f1' at row 2
select f1 + 0e0 from t1;
f1 + 0e0
1.0000000150475e+29
-1.0000000150475e+29
1.0000000150475e+30
-1.0000000150475e+30
1.0000000150475e+30
-1.0000000150475e+30
drop table t1;
End of 5.0 tests
...@@ -222,3 +222,23 @@ drop table t1; ...@@ -222,3 +222,23 @@ drop table t1;
create table t1 (s1 float(0,2)); create table t1 (s1 float(0,2));
--error 1427 --error 1427
create table t1 (s1 float(1,2)); create table t1 (s1 float(1,2));
#
# Bug #28121 "INSERT or UPDATE into DOUBLE(200,0) field being truncated to 31 digits"
#
create table t1 (f1 double(200, 0));
insert into t1 values (1e199), (-1e199);
insert into t1 values (1e200), (-1e200);
insert into t1 values (2e200), (-2e200);
select f1 + 0e0 from t1;
drop table t1;
create table t1 (f1 float(30, 0));
insert into t1 values (1e29), (-1e29);
insert into t1 values (1e30), (-1e30);
insert into t1 values (2e30), (-2e30);
select f1 + 0e0 from t1;
drop table t1;
--echo End of 5.0 tests
...@@ -262,6 +262,34 @@ void my_parameter_handler(const wchar_t * expression, const wchar_t * function, ...@@ -262,6 +262,34 @@ void my_parameter_handler(const wchar_t * expression, const wchar_t * function,
} }
#ifdef __MSVC_RUNTIME_CHECKS
#include <rtcapi.h>
/* Turn off runtime checks for 'handle_rtc_failure' */
#pragma runtime_checks("", off)
/*
handle_rtc_failure
Catch the RTC error and dump it to stderr
*/
int handle_rtc_failure(int err_type, const char *file, int line,
const char* module, const char *format, ...)
{
va_list args;
va_start(args, format);
fprintf(stderr, "Error:");
vfprintf(stderr, format, args);
fprintf(stderr, " At %s:%d\n", file, line);
va_end(args);
(void) fflush(stderr);
return 0; /* Error is handled */
}
#pragma runtime_checks("", on)
#endif
static void my_win_init(void) static void my_win_init(void)
{ {
HKEY hSoftMysql ; HKEY hSoftMysql ;
...@@ -292,6 +320,14 @@ static void my_win_init(void) ...@@ -292,6 +320,14 @@ static void my_win_init(void)
_set_invalid_parameter_handler(my_parameter_handler); _set_invalid_parameter_handler(my_parameter_handler);
#endif #endif
#endif #endif
#ifdef __MSVC_RUNTIME_CHECKS
/*
Install handler to send RTC (Runtime Error Check) warnings
to log file
*/
_RTC_SetErrorFunc(handle_rtc_failure);
#endif
_tzset(); _tzset();
/* apre la chiave HKEY_LOCAL_MACHINES\software\MySQL */ /* apre la chiave HKEY_LOCAL_MACHINES\software\MySQL */
......
...@@ -3675,56 +3675,9 @@ int Field_float::store(const char *from,uint len,CHARSET_INFO *cs) ...@@ -3675,56 +3675,9 @@ int Field_float::store(const char *from,uint len,CHARSET_INFO *cs)
int Field_float::store(double nr) int Field_float::store(double nr)
{ {
float j; int error= truncate(&nr, FLT_MAX);
int error= 0; float j= (float)nr;
if (isnan(nr))
{
j= 0;
set_null();
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else if (unsigned_flag && nr < 0)
{
j= 0;
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else
{
double max_value;
if (dec >= NOT_FIXED_DEC)
{
max_value= FLT_MAX;
}
else
{
uint tmp=min(field_length,array_elements(log_10)-1);
max_value= (log_10[tmp]-1)/log_10[dec];
/*
The following comparison is needed to not get an overflow if nr
is close to FLT_MAX
*/
if (fabs(nr) < FLT_MAX/10.0e+32)
nr= floor(nr*log_10[dec]+0.5)/log_10[dec];
}
if (nr < -max_value)
{
j= (float)-max_value;
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else if (nr > max_value)
{
j= (float)max_value;
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else
j= (float) nr;
}
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first) if (table->s->db_low_byte_first)
{ {
...@@ -3963,48 +3916,7 @@ int Field_double::store(const char *from,uint len,CHARSET_INFO *cs) ...@@ -3963,48 +3916,7 @@ int Field_double::store(const char *from,uint len,CHARSET_INFO *cs)
int Field_double::store(double nr) int Field_double::store(double nr)
{ {
int error= 0; int error= truncate(&nr, DBL_MAX);
if (isnan(nr))
{
nr= 0;
set_null();
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else if (unsigned_flag && nr < 0)
{
nr= 0;
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else
{
double max_value;
if (not_fixed)
{
max_value= DBL_MAX;
}
else
{
uint tmp=min(field_length,array_elements(log_10)-1);
max_value= (log_10[tmp]-1)/log_10[dec];
if (fabs(nr) < DBL_MAX/10.0e+32)
nr= floor(nr*log_10[dec]+0.5)/log_10[dec];
}
if (nr < -max_value)
{
nr= -max_value;
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else if (nr > max_value)
{
nr= max_value;
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
}
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first) if (table->s->db_low_byte_first)
...@@ -4023,6 +3935,63 @@ int Field_double::store(longlong nr, bool unsigned_val) ...@@ -4023,6 +3935,63 @@ int Field_double::store(longlong nr, bool unsigned_val)
return store(unsigned_val ? ulonglong2double((ulonglong) nr) : (double) nr); return store(unsigned_val ? ulonglong2double((ulonglong) nr) : (double) nr);
} }
/*
If a field has fixed length, truncate the double argument pointed to by 'nr'
appropriately.
Also ensure that the argument is within [-max_value; max_value] range.
*/
int Field_real::truncate(double *nr, double max_value)
{
int error= 1;
double res= *nr;
if (isnan(res))
{
res= 0;
set_null();
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
goto end;
}
else if (unsigned_flag && res < 0)
{
res= 0;
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
goto end;
}
if (!not_fixed)
{
uint order= field_length - dec;
uint step= array_elements(log_10) - 1;
max_value= 1.0;
for (; order > step; order-= step)
max_value*= log_10[step];
max_value*= log_10[order];
max_value-= 1.0 / log_10[dec];
double tmp= rint((res - floor(res)) * log_10[dec]) / log_10[dec];
res= floor(res) + tmp;
}
if (res < -max_value)
{
res= -max_value;
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
}
else if (res > max_value)
{
res= max_value;
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
}
else
error= 0;
end:
*nr= res;
return error;
}
int Field_real::store_decimal(const my_decimal *dm) int Field_real::store_decimal(const my_decimal *dm)
{ {
......
...@@ -453,6 +453,7 @@ public: ...@@ -453,6 +453,7 @@ public:
/* base class for float and double and decimal (old one) */ /* base class for float and double and decimal (old one) */
class Field_real :public Field_num { class Field_real :public Field_num {
public: public:
my_bool not_fixed;
Field_real(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, Field_real(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg, utype unireg_check_arg, uchar null_bit_arg, utype unireg_check_arg,
...@@ -460,13 +461,16 @@ public: ...@@ -460,13 +461,16 @@ public:
struct st_table *table_arg, struct st_table *table_arg,
uint8 dec_arg, bool zero_arg, bool unsigned_arg) uint8 dec_arg, bool zero_arg, bool unsigned_arg)
:Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, :Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
field_name_arg, table_arg, dec_arg, zero_arg, unsigned_arg) field_name_arg, table_arg, dec_arg, zero_arg, unsigned_arg),
not_fixed(dec_arg >= NOT_FIXED_DEC)
{} {}
int store_decimal(const my_decimal *); int store_decimal(const my_decimal *);
my_decimal *val_decimal(my_decimal *); my_decimal *val_decimal(my_decimal *);
int truncate(double *nr, double max_length);
uint32 max_display_length() { return field_length; } uint32 max_display_length() { return field_length; }
uint size_of() const { return sizeof(*this); }
}; };
...@@ -758,7 +762,6 @@ public: ...@@ -758,7 +762,6 @@ public:
class Field_double :public Field_real { class Field_double :public Field_real {
public: public:
my_bool not_fixed;
Field_double(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, Field_double(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg, uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg, enum utype unireg_check_arg, const char *field_name_arg,
...@@ -766,21 +769,18 @@ public: ...@@ -766,21 +769,18 @@ public:
uint8 dec_arg,bool zero_arg,bool unsigned_arg) uint8 dec_arg,bool zero_arg,bool unsigned_arg)
:Field_real(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, :Field_real(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg, unireg_check_arg, field_name_arg, table_arg,
dec_arg, zero_arg, unsigned_arg), dec_arg, zero_arg, unsigned_arg)
not_fixed(dec_arg >= NOT_FIXED_DEC)
{} {}
Field_double(uint32 len_arg, bool maybe_null_arg, const char *field_name_arg, Field_double(uint32 len_arg, bool maybe_null_arg, const char *field_name_arg,
struct st_table *table_arg, uint8 dec_arg) struct st_table *table_arg, uint8 dec_arg)
:Field_real((char*) 0, len_arg, maybe_null_arg ? (uchar*) "" : 0, (uint) 0, :Field_real((char*) 0, len_arg, maybe_null_arg ? (uchar*) "" : 0, (uint) 0,
NONE, field_name_arg, table_arg, dec_arg, 0, 0), NONE, field_name_arg, table_arg, dec_arg, 0, 0)
not_fixed(dec_arg >= NOT_FIXED_DEC)
{} {}
Field_double(uint32 len_arg, bool maybe_null_arg, const char *field_name_arg, Field_double(uint32 len_arg, bool maybe_null_arg, const char *field_name_arg,
struct st_table *table_arg, uint8 dec_arg, my_bool not_fixed_srg) struct st_table *table_arg, uint8 dec_arg, my_bool not_fixed_arg)
:Field_real((char*) 0, len_arg, maybe_null_arg ? (uchar*) "" : 0, (uint) 0, :Field_real((char*) 0, len_arg, maybe_null_arg ? (uchar*) "" : 0, (uint) 0,
NONE, field_name_arg, table_arg, dec_arg, 0, 0), NONE, field_name_arg, table_arg, dec_arg, 0, 0)
not_fixed(not_fixed_srg) {not_fixed= not_fixed_arg; }
{}
enum_field_types type() const { return FIELD_TYPE_DOUBLE;} enum_field_types type() const { return FIELD_TYPE_DOUBLE;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_DOUBLE; } enum ha_base_keytype key_type() const { return HA_KEYTYPE_DOUBLE; }
int store(const char *to,uint length,CHARSET_INFO *charset); int store(const char *to,uint length,CHARSET_INFO *charset);
...@@ -795,7 +795,6 @@ public: ...@@ -795,7 +795,6 @@ public:
void sort_string(char *buff,uint length); void sort_string(char *buff,uint length);
uint32 pack_length() const { return sizeof(double); } uint32 pack_length() const { return sizeof(double); }
void sql_type(String &str) const; void sql_type(String &str) const;
uint size_of() const { return sizeof(*this); }
}; };
......
...@@ -21,8 +21,6 @@ ...@@ -21,8 +21,6 @@
void unireg_init(ulong options) void unireg_init(ulong options)
{ {
uint i;
double nr;
DBUG_ENTER("unireg_init"); DBUG_ENTER("unireg_init");
MYSYS_PROGRAM_DONT_USE_CURSES(); MYSYS_PROGRAM_DONT_USE_CURSES();
...@@ -39,16 +37,5 @@ void unireg_init(ulong options) ...@@ -39,16 +37,5 @@ void unireg_init(ulong options)
VOID(strmov(reg_ext,".frm")); VOID(strmov(reg_ext,".frm"));
specialflag=SPECIAL_SAME_DB_NAME | options; /* Set options from argv */ specialflag=SPECIAL_SAME_DB_NAME | options; /* Set options from argv */
/* Make a tab of powers of 10 */
for (i=0,nr=1.0; i < array_elements(log_10) ; i++)
{ /* It's used by filesort... */
log_10[i]= nr ; nr*= 10.0;
}
/* Make a tab of powers of 0.1 */
for (i= 0, nr= 0.1; i < array_elements(log_01); i++)
{
log_01[i]= nr;
nr*= 0.1;
}
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -507,7 +507,7 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type) ...@@ -507,7 +507,7 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
{ {
if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC) if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
{ {
precision= 5 * log_01[max((*a)->decimals, (*b)->decimals)]; precision= 5 * log_01[max((*a)->decimals, (*b)->decimals) + 1];
if (func == &Arg_comparator::compare_real) if (func == &Arg_comparator::compare_real)
func= &Arg_comparator::compare_real_fixed; func= &Arg_comparator::compare_real_fixed;
else if (func == &Arg_comparator::compare_e_real) else if (func == &Arg_comparator::compare_e_real)
......
...@@ -1269,8 +1269,6 @@ extern char language[FN_REFLEN], reg_ext[FN_EXTLEN]; ...@@ -1269,8 +1269,6 @@ extern char language[FN_REFLEN], reg_ext[FN_EXTLEN];
extern char glob_hostname[FN_REFLEN], mysql_home[FN_REFLEN]; extern char glob_hostname[FN_REFLEN], mysql_home[FN_REFLEN];
extern char pidfile_name[FN_REFLEN], system_time_zone[30], *opt_init_file; extern char pidfile_name[FN_REFLEN], system_time_zone[30], *opt_init_file;
extern char log_error_file[FN_REFLEN], *opt_tc_log_file; extern char log_error_file[FN_REFLEN], *opt_tc_log_file;
extern double log_10[32];
extern double log_01[32];
extern ulonglong log_10_int[20]; extern ulonglong log_10_int[20];
extern ulonglong keybuff_size; extern ulonglong keybuff_size;
extern ulonglong thd_startup_options; extern ulonglong thd_startup_options;
......
...@@ -434,8 +434,6 @@ ulong slow_launch_threads = 0, sync_binlog_period; ...@@ -434,8 +434,6 @@ ulong slow_launch_threads = 0, sync_binlog_period;
ulong expire_logs_days = 0; ulong expire_logs_days = 0;
ulong rpl_recovery_rank=0; ulong rpl_recovery_rank=0;
double log_10[32]; /* 10 potences */
double log_01[32];
time_t server_start_time; time_t server_start_time;
char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30]; char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
...@@ -2148,6 +2146,16 @@ later when used with nscd), disable LDAP in your nsswitch.conf, or use a\n\ ...@@ -2148,6 +2146,16 @@ later when used with nscd), disable LDAP in your nsswitch.conf, or use a\n\
mysqld that is not statically linked.\n"); mysqld that is not statically linked.\n");
#endif #endif
#ifdef HAVE_NPTL
if (thd_lib_detected == THD_LIB_LT && !getenv("LD_ASSUME_KERNEL"))
fprintf(stderr,"\n\
You are running a statically-linked LinuxThreads binary on an NPTL system.\n\
This can result in crashes on some distributions due to LT/NPTL conflicts.\n\
You should either build a dynamically-linked binary, or force LinuxThreads\n\
to be used with the LD_ASSUME_KERNEL environment variable. Please consult\n\
the documentation for your distribution on how to do that.\n");
#endif
if (locked_in_memory) if (locked_in_memory)
{ {
fprintf(stderr, "\n\ fprintf(stderr, "\n\
......
...@@ -31,13 +31,74 @@ ...@@ -31,13 +31,74 @@
#define MAX_DBL_EXP 308 #define MAX_DBL_EXP 308
#define MAX_RESULT_FOR_MAX_EXP 1.7976931348623157 #define MAX_RESULT_FOR_MAX_EXP 1.7976931348623157
static double scaler10[] = {
1.0, 1e10, 1e20, 1e30, 1e40, 1e50, 1e60, 1e70, 1e80, 1e90 const double log_10[] = {
}; 1e000, 1e001, 1e002, 1e003, 1e004, 1e005, 1e006, 1e007, 1e008, 1e009,
static double scaler1[] = { 1e010, 1e011, 1e012, 1e013, 1e014, 1e015, 1e016, 1e017, 1e018, 1e019,
1.0, 10.0, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9 1e020, 1e021, 1e022, 1e023, 1e024, 1e025, 1e026, 1e027, 1e028, 1e029,
1e030, 1e031, 1e032, 1e033, 1e034, 1e035, 1e036, 1e037, 1e038, 1e039,
1e040, 1e041, 1e042, 1e043, 1e044, 1e045, 1e046, 1e047, 1e048, 1e049,
1e050, 1e051, 1e052, 1e053, 1e054, 1e055, 1e056, 1e057, 1e058, 1e059,
1e060, 1e061, 1e062, 1e063, 1e064, 1e065, 1e066, 1e067, 1e068, 1e069,
1e070, 1e071, 1e072, 1e073, 1e074, 1e075, 1e076, 1e077, 1e078, 1e079,
1e080, 1e081, 1e082, 1e083, 1e084, 1e085, 1e086, 1e087, 1e088, 1e089,
1e090, 1e091, 1e092, 1e093, 1e094, 1e095, 1e096, 1e097, 1e098, 1e099,
1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109,
1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119,
1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129,
1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139,
1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149,
1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159,
1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169,
1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179,
1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189,
1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199,
1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209,
1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219,
1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229,
1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239,
1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249,
1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259,
1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269,
1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279,
1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289,
1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299,
1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308
}; };
const double log_01[] = {
1e-000,1e-001,1e-002,1e-003,1e-004,1e-005,1e-006,1e-007,1e-008,1e-009,
1e-010,1e-011,1e-012,1e-013,1e-014,1e-015,1e-016,1e-017,1e-018,1e-019,
1e-020,1e-021,1e-022,1e-023,1e-024,1e-025,1e-026,1e-027,1e-028,1e-029,
1e-030,1e-031,1e-032,1e-033,1e-034,1e-035,1e-036,1e-037,1e-038,1e-039,
1e-040,1e-041,1e-042,1e-043,1e-044,1e-045,1e-046,1e-047,1e-048,1e-049,
1e-050,1e-051,1e-052,1e-053,1e-054,1e-055,1e-056,1e-057,1e-058,1e-059,
1e-060,1e-061,1e-062,1e-063,1e-064,1e-065,1e-066,1e-067,1e-068,1e-069,
1e-070,1e-071,1e-072,1e-073,1e-074,1e-075,1e-076,1e-077,1e-078,1e-079,
1e-080,1e-081,1e-082,1e-083,1e-084,1e-085,1e-086,1e-087,1e-088,1e-089,
1e-090,1e-091,1e-092,1e-093,1e-094,1e-095,1e-096,1e-097,1e-098,1e-099,
1e-100,1e-101,1e-102,1e-103,1e-104,1e-105,1e-106,1e-107,1e-108,1e-109,
1e-110,1e-111,1e-112,1e-113,1e-114,1e-115,1e-116,1e-117,1e-118,1e-119,
1e-120,1e-121,1e-122,1e-123,1e-124,1e-125,1e-126,1e-127,1e-128,1e-129,
1e-130,1e-131,1e-132,1e-133,1e-134,1e-135,1e-136,1e-137,1e-138,1e-139,
1e-140,1e-141,1e-142,1e-143,1e-144,1e-145,1e-146,1e-147,1e-148,1e-149,
1e-150,1e-151,1e-152,1e-153,1e-154,1e-155,1e-156,1e-157,1e-158,1e-159,
1e-160,1e-161,1e-162,1e-163,1e-164,1e-165,1e-166,1e-167,1e-168,1e-169,
1e-170,1e-171,1e-172,1e-173,1e-174,1e-175,1e-176,1e-177,1e-178,1e-179,
1e-180,1e-181,1e-182,1e-183,1e-184,1e-185,1e-186,1e-187,1e-188,1e-189,
1e-190,1e-191,1e-192,1e-193,1e-194,1e-195,1e-196,1e-197,1e-198,1e-199,
1e-200,1e-201,1e-202,1e-203,1e-204,1e-205,1e-206,1e-207,1e-208,1e-209,
1e-210,1e-211,1e-212,1e-213,1e-214,1e-215,1e-216,1e-217,1e-218,1e-219,
1e-220,1e-221,1e-222,1e-223,1e-224,1e-225,1e-226,1e-227,1e-228,1e-229,
1e-230,1e-231,1e-232,1e-233,1e-234,1e-235,1e-236,1e-237,1e-238,1e-239,
1e-240,1e-241,1e-242,1e-243,1e-244,1e-245,1e-246,1e-247,1e-248,1e-249,
1e-250,1e-251,1e-252,1e-253,1e-254,1e-255,1e-256,1e-257,1e-258,1e-259,
1e-260,1e-261,1e-262,1e-263,1e-264,1e-265,1e-266,1e-267,1e-268,1e-269,
1e-270,1e-271,1e-272,1e-273,1e-274,1e-275,1e-276,1e-277,1e-278,1e-279,
1e-280,1e-281,1e-282,1e-283,1e-284,1e-285,1e-286,1e-287,1e-288,1e-289,
1e-290,1e-291,1e-292,1e-293,1e-294,1e-295,1e-296,1e-297,1e-298,1e-299,
1e-300,1e-301,1e-302,1e-303,1e-304,1e-305,1e-306,1e-307,1e-308
};
/* /*
Convert string to double (string doesn't have to be null terminated) Convert string to double (string doesn't have to be null terminated)
...@@ -57,7 +118,7 @@ double my_strtod(const char *str, char **end_ptr, int *error) ...@@ -57,7 +118,7 @@ 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 exponent= 0, digits_after_dec_point= 0, tmp_exp; int exponent= 0, digits_after_dec_point= 0, tmp_exp, step;
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;
...@@ -178,17 +239,13 @@ double my_strtod(const char *str, char **end_ptr, int *error) ...@@ -178,17 +239,13 @@ double my_strtod(const char *str, char **end_ptr, int *error)
{ {
exponent= -exponent; exponent= -exponent;
neg_exp= 1; /* neg_exp was 0 before */ neg_exp= 1; /* neg_exp was 0 before */
step= array_elements(log_01) - 1;
} }
while (exponent >= 100)
{
result= neg_exp ? result/1.0e100 : result*1.0e100;
exponent-= 100;
}
scaler= scaler10[exponent/10]*scaler1[exponent%10];
if (neg_exp)
result/= scaler;
else else
result*= scaler; step= array_elements(log_10) - 1;
for (; exponent > step; exponent-= step)
result= neg_exp ? result / log_10[step] : result * log_10[step];
result= neg_exp ? result / log_10[exponent] : result * log_10[exponent];
} }
done: done:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment