Commit 53d2e32b authored by unknown's avatar unknown

Merge bk-internal.mysql.com:/home/bk/mysql-4.1

into  zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-4.1-maint

parents 1e84e31c 41c25e01
...@@ -2629,7 +2629,7 @@ com_connect(String *buffer, char *line) ...@@ -2629,7 +2629,7 @@ com_connect(String *buffer, char *line)
bzero(buff, sizeof(buff)); bzero(buff, sizeof(buff));
if (buffer) if (buffer)
{ {
strmov(buff, line); strmake(buff, line, sizeof(buff) - 1);
tmp= get_arg(buff, 0); tmp= get_arg(buff, 0);
if (tmp && *tmp) if (tmp && *tmp)
{ {
...@@ -2743,7 +2743,7 @@ com_use(String *buffer __attribute__((unused)), char *line) ...@@ -2743,7 +2743,7 @@ com_use(String *buffer __attribute__((unused)), char *line)
char *tmp, buff[FN_REFLEN + 1]; char *tmp, buff[FN_REFLEN + 1];
bzero(buff, sizeof(buff)); bzero(buff, sizeof(buff));
strmov(buff, line); strmake(buff, line, sizeof(buff) - 1);
tmp= get_arg(buff, 0); tmp= get_arg(buff, 0);
if (!tmp || !*tmp) if (!tmp || !*tmp)
{ {
......
...@@ -1352,3 +1352,16 @@ select database(); ...@@ -1352,3 +1352,16 @@ select database();
database() database()
имя_базы_в_кодировке_утф8_длиной_больше_чем_45 имя_базы_в_кодировке_утф8_длиной_больше_чем_45
drop database имя_базы_в_кодировке_утф8_длиной_больше_чем_45; drop database имя_базы_в_кодировке_утф8_длиной_больше_чем_45;
use test;
create table t1(a char(10)) default charset utf8;
insert into t1 values ('123'), ('456');
explain
select substr(Z.a,-1), Z.a from t1 as Y join t1 as Z on Y.a=Z.a order by 1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE Y ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
1 SIMPLE Z ALL NULL NULL NULL NULL 2 Using where
select substr(Z.a,-1), Z.a from t1 as Y join t1 as Z on Y.a=Z.a order by 1;
substr(Z.a,-1) a
3 123
6 456
drop table t1;
...@@ -694,6 +694,18 @@ t1 CREATE TABLE `t1` ( ...@@ -694,6 +694,18 @@ t1 CREATE TABLE `t1` (
`from_unixtime(1) + 0` double(23,6) default NULL `from_unixtime(1) + 0` double(23,6) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1; drop table t1;
SET NAMES latin1;
SET character_set_results = NULL;
SHOW VARIABLES LIKE 'character_set_results';
Variable_name Value
character_set_results
CREATE TABLE testBug8868 (field1 DATE, field2 VARCHAR(32) CHARACTER SET BINARY);
INSERT INTO testBug8868 VALUES ('2006-09-04', 'abcd');
SELECT DATE_FORMAT(field1,'%b-%e %l:%i%p') as fmtddate, field2 FROM testBug8868;
fmtddate field2
Sep-4 12:00AM abcd
DROP TABLE testBug8868;
SET NAMES DEFAULT;
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%H') As H) (select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%H') As H)
union union
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%H') As H); (select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%H') As H);
......
...@@ -272,3 +272,10 @@ desc t3; ...@@ -272,3 +272,10 @@ desc t3;
Field Type Null Key Default Extra Field Type Null Key Default Extra
a double 0 a double 0
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
...@@ -1087,5 +1087,17 @@ create database имя_базы_в_кодировке_утф8_длиной_бо ...@@ -1087,5 +1087,17 @@ create database имя_базы_в_кодировке_утф8_длиной_бо
use имя_базы_в_кодировке_утф8_длиной_больше_чем_45; use имя_базы_в_кодировке_утф8_длиной_больше_чем_45;
select database(); select database();
drop database имя_базы_в_кодировке_утф8_длиной_больше_чем_45; drop database имя_базы_в_кодировке_утф8_длиной_больше_чем_45;
use test;
#
# Bug #20204: "order by" changes the results returned
#
create table t1(a char(10)) default charset utf8;
insert into t1 values ('123'), ('456');
explain
select substr(Z.a,-1), Z.a from t1 as Y join t1 as Z on Y.a=Z.a order by 1;
select substr(Z.a,-1), Z.a from t1 as Y join t1 as Z on Y.a=Z.a order by 1;
drop table t1;
# End of 4.1 tests # End of 4.1 tests
...@@ -368,6 +368,25 @@ create table t1 select now() - now(), curtime() - curtime(), ...@@ -368,6 +368,25 @@ create table t1 select now() - now(), curtime() - curtime(),
show create table t1; show create table t1;
drop table t1; drop table t1;
#
# 21913: DATE_FORMAT() Crashes mysql server if I use it through
# mysql-connector-j driver.
#
SET NAMES latin1;
SET character_set_results = NULL;
SHOW VARIABLES LIKE 'character_set_results';
CREATE TABLE testBug8868 (field1 DATE, field2 VARCHAR(32) CHARACTER SET BINARY);
INSERT INTO testBug8868 VALUES ('2006-09-04', 'abcd');
SELECT DATE_FORMAT(field1,'%b-%e %l:%i%p') as fmtddate, field2 FROM testBug8868;
DROP TABLE testBug8868;
SET NAMES DEFAULT;
# #
# Bug #19844 time_format in Union truncates values # Bug #19844 time_format in Union truncates values
# #
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
# i.e. lower_case_filesystem=OFF # i.e. lower_case_filesystem=OFF
# #
-- source include/have_case_sensitive_file_system.inc -- source include/have_case_sensitive_file_system.inc
-- source include/not_embedded.inc
connect (master,localhost,root,,); connect (master,localhost,root,,);
connection master; connection master;
......
...@@ -179,4 +179,13 @@ show warnings; ...@@ -179,4 +179,13 @@ 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
...@@ -7,6 +7,6 @@ ndbapiincludedir = "$(pkgincludedir)/ndb/ndbapi" ...@@ -7,6 +7,6 @@ ndbapiincludedir = "$(pkgincludedir)/ndb/ndbapi"
mgmapiincludedir = "$(pkgincludedir)/ndb/mgmapi" mgmapiincludedir = "$(pkgincludedir)/ndb/mgmapi"
INCLUDES = $(INCLUDES_LOC) INCLUDES = $(INCLUDES_LOC)
LDADD = $(top_srcdir)/ndb/src/common/portlib/gcc.cpp $(LDADD_LOC) LDADD = $(LDADD_LOC) -L$(top_srcdir)/ndb/src/common/portlib -lmygcc
DEFS = @DEFS@ @NDB_DEFS@ $(DEFS_LOC) $(NDB_EXTRA_FLAGS) DEFS = @DEFS@ @NDB_DEFS@ $(DEFS_LOC) $(NDB_EXTRA_FLAGS)
NDB_CXXFLAGS=@ndb_cxxflags_fix@ $(NDB_CXXFLAGS_LOC) NDB_CXXFLAGS=@ndb_cxxflags_fix@ $(NDB_CXXFLAGS_LOC)
...@@ -3,7 +3,7 @@ LDADD += \ ...@@ -3,7 +3,7 @@ LDADD += \
$(top_builddir)/ndb/src/libndbclient.la \ $(top_builddir)/ndb/src/libndbclient.la \
$(top_builddir)/dbug/libdbug.a \ $(top_builddir)/dbug/libdbug.a \
$(top_builddir)/mysys/libmysys.a \ $(top_builddir)/mysys/libmysys.a \
$(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@ $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@ -lmygcc
INCLUDES += -I$(srcdir) -I$(top_srcdir)/include \ INCLUDES += -I$(srcdir) -I$(top_srcdir)/include \
-I$(top_srcdir)/ndb/include \ -I$(top_srcdir)/ndb/include \
......
noinst_HEADERS = gcc.cpp noinst_LIBRARIES = libmygcc.a
libmygcc_a_SOURCES = gcc.cpp
noinst_LTLIBRARIES = libportlib.la noinst_LTLIBRARIES = libportlib.la
......
...@@ -53,7 +53,8 @@ LDADD += \ ...@@ -53,7 +53,8 @@ LDADD += \
$(top_builddir)/ndb/src/common/util/libgeneral.la \ $(top_builddir)/ndb/src/common/util/libgeneral.la \
$(top_builddir)/dbug/libdbug.a \ $(top_builddir)/dbug/libdbug.a \
$(top_builddir)/mysys/libmysys.a \ $(top_builddir)/mysys/libmysys.a \
$(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@ $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@ -lmygcc
# Don't update the files from bitkeeper # Don't update the files from bitkeeper
%::SCCS/s.% %::SCCS/s.%
......
...@@ -1109,12 +1109,13 @@ void Item_func_substr::fix_length_and_dec() ...@@ -1109,12 +1109,13 @@ void Item_func_substr::fix_length_and_dec()
} }
if (arg_count == 3 && args[2]->const_item()) if (arg_count == 3 && args[2]->const_item())
{ {
int32 length= (int32) args[2]->val_int() * collation.collation->mbmaxlen; int32 length= (int32) args[2]->val_int();
if (length <= 0) if (length <= 0)
max_length=0; /* purecov: inspected */ max_length=0; /* purecov: inspected */
else else
set_if_smaller(max_length,(uint) length); set_if_smaller(max_length,(uint) length);
} }
max_length*= collation.collation->mbmaxlen;
} }
......
...@@ -6552,10 +6552,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), ...@@ -6552,10 +6552,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
} }
switch (method-1) { switch (method-1) {
case 0: case 0:
method_conv= MI_STATS_METHOD_NULLS_EQUAL; method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL;
break; break;
case 1: case 1:
method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL; method_conv= MI_STATS_METHOD_NULLS_EQUAL;
break; break;
case 2: case 2:
method_conv= MI_STATS_METHOD_IGNORE_NULLS; method_conv= MI_STATS_METHOD_IGNORE_NULLS;
......
...@@ -248,6 +248,10 @@ bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *cs) ...@@ -248,6 +248,10 @@ bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *cs)
0 No conversion needed 0 No conversion needed
1 Either character set conversion or adding leading zeros 1 Either character set conversion or adding leading zeros
(e.g. for UCS-2) must be done (e.g. for UCS-2) must be done
NOTE
to_cs may be NULL for "no conversion" if the system variable
character_set_results is NULL.
*/ */
bool String::needs_conversion(uint32 arg_length, bool String::needs_conversion(uint32 arg_length,
...@@ -256,7 +260,8 @@ bool String::needs_conversion(uint32 arg_length, ...@@ -256,7 +260,8 @@ bool String::needs_conversion(uint32 arg_length,
uint32 *offset) uint32 *offset)
{ {
*offset= 0; *offset= 0;
if ((to_cs == &my_charset_bin) || if (!to_cs ||
(to_cs == &my_charset_bin) ||
(to_cs == from_cs) || (to_cs == from_cs) ||
my_charset_same(from_cs, to_cs) || my_charset_same(from_cs, to_cs) ||
((from_cs == &my_charset_bin) && ((from_cs == &my_charset_bin) &&
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#ifdef HAVE_STACKTRACE #ifdef HAVE_STACKTRACE
#include <unistd.h> #include <unistd.h>
#include <strings.h>
#define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end) #define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end)
...@@ -44,7 +45,29 @@ void safe_print_str(const char* name, const char* val, int max_len) ...@@ -44,7 +45,29 @@ void safe_print_str(const char* name, const char* val, int max_len)
} }
#ifdef TARGET_OS_LINUX #ifdef TARGET_OS_LINUX
#define SIGRETURN_FRAME_COUNT 2
#ifdef __i386__
#define SIGRETURN_FRAME_OFFSET 17
#endif
#ifdef __x86_64__
#define SIGRETURN_FRAME_OFFSET 23
#endif
static my_bool is_nptl;
/* Check if we are using NPTL or LinuxThreads on Linux */
void check_thread_lib(void)
{
char buf[5];
#ifdef _CS_GNU_LIBPTHREAD_VERSION
confstr(_CS_GNU_LIBPTHREAD_VERSION, buf, sizeof(buf));
is_nptl = !strncasecmp(buf, "NPTL", sizeof(buf));
#else
is_nptl = 0;
#endif
}
#if defined(__alpha__) && defined(__GNUC__) #if defined(__alpha__) && defined(__GNUC__)
/* /*
...@@ -90,7 +113,7 @@ inline uint32* find_prev_pc(uint32* pc, uchar** fp) ...@@ -90,7 +113,7 @@ inline uint32* find_prev_pc(uint32* pc, uchar** fp)
void print_stacktrace(gptr stack_bottom, ulong thread_stack) void print_stacktrace(gptr stack_bottom, ulong thread_stack)
{ {
uchar** fp; uchar** fp;
uint frame_count = 0; uint frame_count = 0, sigreturn_frame_count;
#if defined(__alpha__) && defined(__GNUC__) #if defined(__alpha__) && defined(__GNUC__)
uint32* pc; uint32* pc;
#endif #endif
...@@ -100,28 +123,27 @@ void print_stacktrace(gptr stack_bottom, ulong thread_stack) ...@@ -100,28 +123,27 @@ void print_stacktrace(gptr stack_bottom, ulong thread_stack)
Attempting backtrace. You can use the following information to find out\n\ Attempting backtrace. You can use the following information to find out\n\
where mysqld died. If you see no messages after this, something went\n\ where mysqld died. If you see no messages after this, something went\n\
terribly wrong...\n"); terribly wrong...\n");
#ifdef __i386__ #ifdef __i386__
__asm __volatile__ ("movl %%ebp,%0" __asm __volatile__ ("movl %%ebp,%0"
:"=r"(fp) :"=r"(fp)
:"r"(fp)); :"r"(fp));
if (!fp) #endif
{ #ifdef __x86_64__
fprintf(stderr, "frame pointer (ebp) is NULL, did you compile with\n\ __asm __volatile__ ("movq %%rbp,%0"
-fomit-frame-pointer? Aborting backtrace!\n"); :"=r"(fp)
return; :"r"(fp));
}
#endif #endif
#if defined(__alpha__) && defined(__GNUC__) #if defined(__alpha__) && defined(__GNUC__)
__asm __volatile__ ("mov $30,%0" __asm __volatile__ ("mov $30,%0"
:"=r"(fp) :"=r"(fp)
:"r"(fp)); :"r"(fp));
#endif
if (!fp) if (!fp)
{ {
fprintf(stderr, "frame pointer (fp) is NULL, did you compile with\n\ fprintf(stderr, "frame pointer is NULL, did you compile with\n\
-fomit-frame-pointer? Aborting backtrace!\n"); -fomit-frame-pointer? Aborting backtrace!\n");
return; return;
} }
#endif /* __alpha__ */
if (!stack_bottom || (gptr) stack_bottom > (gptr) &fp) if (!stack_bottom || (gptr) stack_bottom > (gptr) &fp)
{ {
...@@ -151,13 +173,16 @@ terribly wrong...\n"); ...@@ -151,13 +173,16 @@ terribly wrong...\n");
:"r"(pc)); :"r"(pc));
#endif /* __alpha__ */ #endif /* __alpha__ */
/* We are 1 frame above signal frame with NPTL and 2 frames above with LT */
sigreturn_frame_count = is_nptl ? 1 : 2;
while (fp < (uchar**) stack_bottom) while (fp < (uchar**) stack_bottom)
{ {
#ifdef __i386__ #if defined(__i386__) || defined(__x86_64__)
uchar** new_fp = (uchar**)*fp; uchar** new_fp = (uchar**)*fp;
fprintf(stderr, "%p\n", frame_count == SIGRETURN_FRAME_COUNT ? fprintf(stderr, "%p\n", frame_count == sigreturn_frame_count ?
*(fp+17) : *(fp+1)); *(fp + SIGRETURN_FRAME_OFFSET) : *(fp + 1));
#endif /* __386__ */ #endif /* defined(__386__) || defined(__x86_64__) */
#if defined(__alpha__) && defined(__GNUC__) #if defined(__alpha__) && defined(__GNUC__)
uchar** new_fp = find_prev_fp(pc, fp); uchar** new_fp = find_prev_fp(pc, fp);
......
...@@ -19,16 +19,20 @@ extern "C" { ...@@ -19,16 +19,20 @@ extern "C" {
#endif #endif
#ifdef TARGET_OS_LINUX #ifdef TARGET_OS_LINUX
#if defined(HAVE_STACKTRACE) || (defined (__i386__) || (defined(__alpha__) && defined(__GNUC__))) #if defined(HAVE_STACKTRACE) || (defined (__x86_64__) || defined (__i386__) || (defined(__alpha__) && defined(__GNUC__)))
#undef HAVE_STACKTRACE #undef HAVE_STACKTRACE
#define HAVE_STACKTRACE #define HAVE_STACKTRACE
extern char* __bss_start; extern char* __bss_start;
extern char* heap_start; extern char* heap_start;
#define init_stacktrace() { heap_start = (char*) &__bss_start; } #define init_stacktrace() do { \
heap_start = (char*) &__bss_start; \
check_thread_lib(); \
} while(0);
void print_stacktrace(gptr stack_bottom, ulong thread_stack); void print_stacktrace(gptr stack_bottom, ulong thread_stack);
void safe_print_str(const char* name, const char* val, int max_len); void safe_print_str(const char* name, const char* val, int max_len);
void check_thread_lib(void);
#endif /* (defined (__i386__) || (defined(__alpha__) && defined(__GNUC__))) */ #endif /* (defined (__i386__) || (defined(__alpha__) && defined(__GNUC__))) */
#endif /* TARGET_OS_LINUX */ #endif /* TARGET_OS_LINUX */
......
...@@ -30,7 +30,8 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
if (exp < 0) /*
{ Check for underflow/overflow.
exp= -exp; order is such an integer number that f = C * 10 ^ order,
neg_exp= 1; /* neg_exp was 0 before */ where f is the resulting floating point number and 1 <= C < 10.
} Here we compute the modulus
if (exp + ndigits >= MAX_DBL_EXP + 1 && result) */
order= exp + (neg_exp ? -1 : 1) * (ndigits - 1);
if (order < 0)
order= -order;
if (order >= MAX_DBL_EXP && result)
{ {
/* double c;
This is not 100 % as we actually will give an owerflow for /* Compute modulus of C (see comment above) */
17E307 but not for 1.7E308 but lets cut some corners to make life c= result / scaler * 10.0;
simpler if (neg_exp)
*/
if (exp + ndigits > MAX_DBL_EXP + 1 ||
result >= MAX_RESULT_FOR_MAX_EXP)
{ {
if (neg_exp) if (order > MAX_DBL_EXP || c < MIN_RESULT_FOR_MIN_EXP)
{
result= 0.0; result= 0.0;
else goto done;
}
}
else
{
if (order > MAX_DBL_EXP || c > MAX_RESULT_FOR_MAX_EXP)
{
overflow= 1; overflow= 1;
goto done; goto done;
}
} }
} }
scaler= 1.0;
exp= tmp_exp;
if (exp < 0)
{
exp= -exp;
neg_exp= 1; /* neg_exp was 0 before */
}
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
......
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