diff --git a/exe/Sort.exe b/exe/Sort.exe index b8f6282..bc049ec 100644 Binary files a/exe/Sort.exe and b/exe/Sort.exe differ diff --git a/src/convert.h b/src/convert.h new file mode 100644 index 0000000..45046d1 --- /dev/null +++ b/src/convert.h @@ -0,0 +1,270 @@ +#pragma once + +typedef long long LL; + +extern double dpow[310], lpow[310]; +extern int pw[5]; + +inline int TypeConvertInit() { + dpow[0] = 1.0; + int i = 1; + for (i = 1; i < 309; ++i) dpow[i] = dpow[i - 1] * 0.1; + lpow[0] = 1.0L; + for (i = 1; i < 309; ++i) lpow[i] = lpow[i - 1] * 10.L; + pw[0] = 1; + for (i = 1; i < 4; ++i) pw[i] = pw[i - 1] * 10; + return 0; +} + +inline bool IsDigit(char c) { + if ((c - '0' > 9) || (c - '0' < 0)) return 0; + return 1; +} + +inline bool IsAlpha(char c) { + if ((c == 'e') || (c == 'E') || (c == '.')) return 1; + return 0; +} + +#ifdef DIVIDE_SORT +// reference: http://www.leapsecond.com/tools/fast_atof.c +double FastCToF(char* c, int ep, int dotp) { + double fig = 0; + + int i = 0; + double sign = 1.0; //plus or minus + int signs = 1, expon = 0;//signs-index sign,expon-index + double scale = 1.0;//scale, 10 to the exponent + if (c[i] == '-') { + sign = -1.0; + i++; + } + if (c[i] == '+') { + i++; + } + + //has exponential bit + if (ep != -1) { + // base is not a decimal + if (dotp == -1) { + for (i; i < ep; i++) + fig = fig * 10.0 + (c[i] - '0'); + } + else { + //get integer part + //If . comes out front, fig=0 + for (i; i < dotp; i++) + fig = fig * 10.0 + (c[i] - '0'); + i++; + //get decimal part + for (i; i < ep; i++) + fig += (c[i] - '0') * dpow[i - dotp]; + } + fig *= sign; + + i++;// skip e or E + if (c[i] == '+') { + i++; + } + if (c[i] == '-') { + signs = -1.0; + i++; + } + //index part + for (i; IsDigit(c[i]); i++) + expon = expon * 10 + (c[i] - '0'); + + while (expon >= 200) { scale *= 1E200; expon -= 200; } + while (expon >= 80) { scale *= 1E80; expon -= 80; } + while (expon >= 30) { scale *= 1E30; expon -= 30; } + while (expon >= 12) { scale *= 1E12; expon -= 12; } + while (expon >= 5) { scale *= 1E5; expon -= 5; } + while (expon > 0) { scale *= 10.0; expon -= 1; } + + if (signs > 0) fig *= scale; + if (signs < 0) fig /= scale; + } + else { + // base is not a decimal + if (dotp == -1) { + for (i; IsDigit(c[i]); i++) + fig = fig * 10.0 + (c[i] - '0'); + } + else { + for (i; i < dotp; i++) + fig = fig * 10.0 + (c[i] - '0'); + i++; + for (i; IsDigit(c[i]); i++) + fig += (c[i] - '0') * dpow[i - dotp]; + } + fig *= sign; + } + return fig; +} +#endif + + +#ifdef MERGE_SORT +char* FastFToC(char* buf, double number) { + int i = 0, num = 0, l = 0, r = 308, mid, ln; + double tmp = 0.00; + + if (number == -5*dpow[308]*dpow[10]) { //number == 0.0; + //if (number < 0) (*buf++) = '-'; + *(buf++) = '0'; + *(buf++) = '.'; + for (i = 0; i < 9; ++i) *(buf++) = '0'; + *(buf++) = 'E'; + *(buf++) = '+'; + for (i = 0; i < 3; ++i) *(buf++) = '0'; + *(buf++) = 0x0a; + return buf; + } + + LL lnum = *(LL*)(&number); + if (number < 0) { // get the absolute value + lnum &= (0x7FFFFFFFFFFFFFFF); + *(buf++) = '-'; + } + + // compensate loss of precision, for example 6.2E-308 can't print 6.19999999E-308 + lnum += 0x0000000000000400; + number = *(double*)(&lnum); + + // if (number >= 1.00 && number < 10.00) number += 5e-10; //round + // number beloings to [1.00,10.00); + if (number >= 1.00 && number < 10.00) { + *(buf++) = ('0' + (LL)(number)); + *(buf++) = '.'; + number = number - (LL)(number); + number *= 10; + for (i = 0; i < 9; ++i) { + ln = (LL)number; + *(buf++) = ('0' + ln); + number -= ln; + number *= 10; + } + *(buf++) = 'E'; + *(buf++) = '+'; + for (i = 0; i < 3; ++i) *(buf++) = '0'; + *(buf++) = 0x0a; + return buf; + } + // number >= 10.00; + else if (number >= 10.00) { + while (l <= r) { //binary search for decimal exponent + mid = (l + r) >> 1; + tmp = number / lpow[mid]; + if (tmp >= 10.00) { + l = mid + 1; + } + else if (tmp < 1.00) { + r = mid - 1; + } + else break; + } + number /= lpow[mid]; + ln = (LL)number; + *(buf++) = ('0' + ln); + *(buf++) = '.'; + number -= ln; + number *= 10; + for (i = 0; i < 9; ++i) { + ln = (LL)number; + *(buf++) = ('0' + ln); + number -= ln; + number *= 10; + } + *(buf++) = 'E'; + *(buf++) = '+'; + for (i = 2; i >= 0; --i) { + *(buf++) = '0' + (mid / pw[i]); + mid %= pw[i]; + } + *(buf++) = 0x0a; + return buf; + } + // number < 1.00 and number>0.00 + else if (number < 1.00) { + while (l <= r) {//binary search for decimal exponent + mid = (l + r) >> 1; + tmp = number * lpow[mid]; + if (tmp >= 10.00) { + r = mid - 1; + } + else if (tmp < 1.00) { + l = mid + 1; + } + else break; + } + number *= lpow[mid]; + ln = (LL)number; + *(buf++) = ('0' + ln); + *(buf++) = '.'; + number -= ln; + number *= 10; + for (i = 0; i < 9; ++i) { + ln = (LL)number; + *(buf++) = ('0' + ln); + number -= ln; + number *= 10; + } + *(buf++) = 'E'; + *(buf++) = '-'; + for (i = 2; i >= 0; --i) { + *(buf++) = '0' + (mid / pw[i]); + mid %= pw[i]; + } + *(buf++) = 0x0a; + return buf; + } + return buf; + +} + +//add 5 to the significant digit +double Round(double t, int n) { + //Absolute + LL t_ll = *(LL*)(&t); + if (t < 0) t_ll &= (0x7FFFFFFFFFFFFFFF); + double t_abs = *(double*)(&t_ll); + + int l = 0, r = 308, mid; + double tmp = 0.00; + if (t_abs >= 1.00) { + while (l <= r) { //binary search for decimal exponent + mid = (l + r) >> 1; + tmp = t_abs / lpow[mid]; + if (tmp >= 10.00) l = mid + 1; + else if (tmp < 1.00) r = mid - 1; + else break; + }//mid is exponent + if (mid <= n) { + if (t > 0) t += 5 * dpow[n - mid]; + else t -= 5 * dpow[n - mid]; + } + else { + if (t > 0) t += 5 * lpow[mid - n]; + else t -= 5 * lpow[mid - n]; + } + } + else { + while (l <= r) { + mid = (l + r) >> 1; + tmp = t_abs * lpow[mid]; + if (tmp >= 10.00) r = mid - 1; + else if (tmp < 1.00) l = mid + 1; + else break; + }//-mid is exponent + if (mid <= 308 - n) { + if (t > 0) t += 5 * dpow[n + mid]; + else t -= 5 * dpow[n + mid]; + } + else { + if (t > 0) t += 5 * dpow[308] * dpow[n + mid - 308]; + else t -= 5 * dpow[308] * dpow[n + mid - 308]; + } + } + return t; +} +#endif diff --git a/src/divide.cpp b/src/divide.cpp index 1565716..969b280 100644 --- a/src/divide.cpp +++ b/src/divide.cpp @@ -1,7 +1,7 @@ #define DIVIDE_SORT #include "divide.h" -#include "type_convert.h" +#include "convert.h" typedef long long LL; const LL MAX_INT64D = 0x7FF0000000000000 - 1; @@ -31,7 +31,7 @@ bool DivideSort::Sort() { FILE* fin = fopen(param_.fpath_input_.c_str(), "rb"); int read_offset = 0, i = 0; - printf("%d small file read char: ", tmp_count_); + printf("%d temp read & convert char: ", tmp_count_); while (!feof(fin)){ num_in_sort_ = 0; while (num_in_sort_ < (param_.num_sort_once_) && !feof(fin)) { @@ -56,11 +56,13 @@ bool DivideSort::Sort() { InternalSort(); } + putchar('\r'); //Print for Screen + free(unsort_double_); free(unsort_char_); + free(tmp_filename_); fclose(fin); - - putchar('\r'); //Print for Screen + return true; } @@ -159,17 +161,18 @@ int DivideSort::SkipIllegal(char* str, int strl, int i_char) { } int DivideSort::InternalSort() { - tmp_num_sort_[tmp_count_] = num_in_sort_; - printf("\ninternal num: %d, now sorted: %d, ", num_in_sort_, sum_sort_); + tmp_num_sort_.push_back(num_in_sort_); + printf("\ninternal: %d, ", num_in_sort_); RadixSort(); - printf("sort OK! "); + printf("sort ok, "); WriteFile(GetTmpFileName(), unsort_double_, num_in_sort_); - printf("write %s\n", GetTmpFileName()); + printf("write %s, ", GetTmpFileName()); + printf("sorted: %d\n", sum_sort_); tmp_count_++; - printf("%d small file read char: ", tmp_count_); + printf("%d temp read & convert char: ", tmp_count_); return 0; } diff --git a/src/divide.h b/src/divide.h index ec0c55f..9bf50d0 100644 --- a/src/divide.h +++ b/src/divide.h @@ -1,8 +1,8 @@ -#pragma once #ifndef DIVIDE_H_ #define DIVIDE_H_ #include +#include #include #include "param.h" @@ -16,24 +16,25 @@ class DivideSort{ inline int SetTmpCount(int tmp_count) { tmp_count_ = tmp_count; }; inline int GetSumSort() { return sum_sort_; }; inline int GetIllegalNum() { return illegal_item_.size(); }; + inline std::vector GetTmpNumSort() { return tmp_num_sort_; }; inline char* GetTmpFileName() { sprintf(tmp_filename_, "temp%d.txt\0", tmp_count_); return tmp_filename_; }; + bool Sort(); int PrintIllegal(const char* fmt = "Illegal item: unsort file %d line:\t%s\n"); private: const Param& param_ = Param::GetInstance(); char* tmp_filename_ = (char*)malloc(param_.max_len_tmpname_ * sizeof(char)); - int* tmp_num_sort_ = (int*)calloc(param_.max_num_file_, sizeof(int));//init 0 - //int tmp_num_sort_[param_.max_num_file_] {0};//非静态成员引用必须与特定对象相对 std::map illegal_item_; int sum_sort_; int tmp_count_; + std::vector tmp_num_sort_; int num_in_char_; int num_in_sort_; diff --git a/src/main.cpp b/src/main.cpp index fba72a4..4b79fde 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,16 +1,20 @@ -#define TYPE_CONVERT_INIT - #include #include +#include #include "param.h" #include "divide.h" -#include "type_convert.h" +#include "merge.h" +#include "convert.h" + +// set table to speed up +double dpow[310], lpow[310]; +int pw[5]; int main(){ - time_t time_now, time_start, time_end; + time_t time_now, time_start, time_end, time_mid; time_start = clock(); time(&time_now); - printf("------start at: %s\n", ctime(&time_now)); + printf("------Start at: %s\n", ctime(&time_now)); TypeConvertInit(); @@ -27,28 +31,33 @@ int main(){ } - printf("---Start block dividing and internal sorting...\n"); + printf("---Start block dividing & internal sorting...\n"); DivideSort divide_sort; if (!divide_sort.Sort()) { - printf("[Error] There is a problem with the unsort file!\n"); + printf("[Error] There is a problem in the divide section!\n"); } - printf("---Divide complete! Small files: %d, Valid float: %d, Time:%dms\n", + time_mid = clock(); + printf("---Divide complete! Small files: %d, Valid float: %d, Time: %I64dms\n", divide_sort.GetTmpCount(), divide_sort.GetSumSort(), - clock() - time_start); + time_mid - time_start); - printf("---Start sorted small block merging...\n"); + printf("---Start small block merge sorting...\n"); + MergeSort merge_sort; + if (!merge_sort.Merge(divide_sort.GetTmpNumSort())) { + printf("[Error] There is a problem in the merge section!\n"); + } + printf("---Merge complete! Time: %I64dms\n", clock() - time_mid); - - printf("---total invalid num: %d\n", divide_sort.GetIllegalNum()); + printf("---Total invalid num: %d\n", divide_sort.GetIllegalNum()); divide_sort.PrintIllegal(); - printf("---total time: %ldms\n", (clock() - time_start)); + printf("---Total time: %I64dms\n", (clock() - time_start)); time(&time_now); - printf("\n------end at: %s", ctime(&time_now)); + printf("\n------End at: %s", ctime(&time_now)); - printf("Type ENTER to exit.\n", ctime(&time_now)); + printf("Type ENTER to exit.\n"); getchar(); return 0; } \ No newline at end of file diff --git a/src/merge.cpp b/src/merge.cpp index a03d54d..5497d17 100644 --- a/src/merge.cpp +++ b/src/merge.cpp @@ -1,11 +1,164 @@ +#define MERGE_SORT + +#include #include "merge.h" #include "param.h" +#include "convert.h" + +typedef long long LL; + +bool MergeSort::Merge(std::vector tmp_num_sort) { + const Param& param = Param::GetInstance(); + + int k = tmp_num_sort.size(); + int sum_sort = std::accumulate(tmp_num_sort.begin(), tmp_num_sort.end(), 0); + FILE* fout = fopen(param.fpath_output_.c_str(), "wb"); + FILE** ftmp = (FILE**)malloc(k * sizeof(FILE*)); + + // block sorted file pointer init + char* tmp_filename = (char*)malloc(param.max_len_tmpname_ * sizeof(char*)); + for (int i = 0; i < k; i++) { + GetTmpFileName(tmp_filename, i); + ftmp[i] = fopen(tmp_filename, "rb"); + } + + int num_read_k = param.num_read_double_ / k; + double** block_sorted = new double* [k]; + for (int i = 0; i < k; i++) + block_sorted[i] = new double[num_read_k]; + std::vector num_read(k);//one sorted block once read double num + std::vector index_next(k);//next merge index + + // first load block sorted file + for (int i = 0; i < k; i++) { + if ((tmp_num_sort[i] + 1) > num_read_k) {// max_double at the end, so+1 + fread(block_sorted[i], sizeof(double), num_read_k, ftmp[i]); + num_read[i] = num_read_k; + tmp_num_sort[i] -= num_read_k; + index_next[i] = 0; + } + else { + fread(block_sorted[i], sizeof(double), (tmp_num_sort[i] + 1), ftmp[i]); + num_read[i] = tmp_num_sort[i] + 1; + tmp_num_sort[i] = 0; + index_next[i] = 0; + } + //printf("read %d\n", num_read[q]); + } + + // loser tree + std::vector b(k+1); + //initialize the leaf node + for (int i = 0; i < k; i++) { + b[i] = block_sorted[i][index_next[i]]; + index_next[i]++; + } + + std::vector ls(k); //intermediate node + //must be initialized to a minimum. + //intermediate nodes are the winners of the subtree + for (int i = 0; i < k; i++) + ls[i] = k; + + CreateLoserTree(b, ls, k); + printf("Init loser tree. Start k-merge sorting...\n"); + + int q = 0;//minimum leaf index + char* write_chars = new char[param.num_write_char_]; + char* buf = write_chars; + int sum_merge = 0; + int one_merge = 0; + while (sum_merge < sum_sort) {//(MAX_DOUBLE>b[ls[0]]) //i != sum_sort + q = ls[0];//ls[0] is final winner's leaf index, minimum + + //write. write is also needed at the end of the loop + if (&write_chars[param.num_write_char_ - 1] - buf > 17) { + buf = FastFToC(buf, Round(b[q], 10));//Including final 0x0a + ++one_merge; + ++sum_merge; + } + else { + fwrite(write_chars, sizeof(char), buf - write_chars, fout); + printf("write sorted: %d,\tcompleted: %d\n", one_merge, sum_merge); + + buf = write_chars; + buf = FastFToC(buf, Round(b[q], 10));//including final 0x0a + one_merge = 1; + ++sum_merge; + } + + //adjust loser tree leaf data + if (num_read[q] > index_next[q]){ + //printf("%d\t%d\t%lf\n", q, index_next[q], b[q]); + b[q] = block_sorted[q][index_next[q]]; + index_next[q]++; + } + else {//reload data + if ((tmp_num_sort[q] + 1) > num_read_k) { + fread(block_sorted[q], sizeof(double), num_read_k, ftmp[q]); + tmp_num_sort[q] -= num_read_k; + index_next[q] = 0; + } + else { //((tmp_num_sort[q]+1)>0) + fread(block_sorted[q], sizeof(double), (tmp_num_sort[q] + 1), ftmp[q]); + num_read[q] = tmp_num_sort[q] + 1; + tmp_num_sort[q] = 0; + index_next[q] = 0; + } + //printf("read %d\n", num_read[q]); + b[q] = block_sorted[q][index_next[q]]; + index_next[q]++; + } + Adjust(q, k, b, ls); + } + fwrite(write_chars, sizeof(char), buf - write_chars, fout); + printf("write sorted: %d,\tcompleted: %d\n", one_merge, sum_merge); + + for (int i = 0; i < k; i++) {//close block temp file + fclose(ftmp[i]); + } + for (int i = 0; i < k; i++) {//remove temp file + GetTmpFileName(tmp_filename, i); + if (remove(tmp_filename) != 0){ + printf("[Error] Failed to delete %s\n", tmp_filename); + } + } + + for (int i = 0; i < k; i++)// first, recycle 2nd dynamic array + delete[] block_sorted[i]; + delete[] block_sorted; + + delete[] write_chars; + free(tmp_filename); -bool MergeSort::Merge(const int* tmp_num_sort) { - const Param& param_ = Param::GetInstance(); + free(ftmp); + fclose(fout); - int tmp_count; + return true; +} +int MergeSort::CreateLoserTree(std::vector& b, std::vector& ls, int k) { + b[k] = -DBL_MAX; //DBL_MIN is >0 min + for (int i = k - 1; i >= 0; i--) + Adjust(i, k, b, ls);//from [k-1],b[k-2]...b[0] + return 0; +} +// reference: http://gengning938.blog.163.com/blog/static/12822538120115131197839/ +int MergeSort::Adjust(int s, int k, std::vector& b, std::vector& ls) { + //from leaf b[s] to root ls[0] + //s update to the winner leaf index + //ls[0] is final winner, minimum + int tmp, t = (s + k) / 2;//ls[t] is b[s] parent + while (t > 0) { + if (b[s] > b[ls[t]]) {//if fail, stay in ls[t] + tmp = s; + s = ls[t]; + ls[t] = tmp; + } + t = t / 2; + } + ls[0] = s; + return 0; } \ No newline at end of file diff --git a/src/merge.h b/src/merge.h index bb3e2da..2612e86 100644 --- a/src/merge.h +++ b/src/merge.h @@ -1,23 +1,24 @@ -#pragma once #ifndef MERGE_H_ #define MERGE_H_ +# include class MergeSort{ public: MergeSort() {}; ~MergeSort() {}; - bool Merge(const int*); + bool Merge(std::vector tmp_num_sort); + inline void GetTmpFileName(char* tmp_filename, int i) { + sprintf(tmp_filename, "temp%d.txt\0", i); + }; private: - + int CreateLoserTree(std::vector& b, std::vector& ls, int k); + int Adjust(int s, int k, std::vector& b, std::vector& ls); }; - - - #endif // ! MERGE_H_ diff --git a/src/param.cpp b/src/param.cpp index 00d5ac5..5f12e7c 100644 --- a/src/param.cpp +++ b/src/param.cpp @@ -6,7 +6,7 @@ int Param::Print(const char* fmt) { return 0; } -bool IsFileExist(const std::string fpath) { +bool IsFileExist(const std::string& fpath) { std::ifstream file(fpath.c_str()); if (!file) { file.close(); @@ -38,6 +38,8 @@ bool ParseParam(const std::string& fpath) { else if (key == "num_sort_once") param.num_sort_once_ = stoi(value); else if (key == "num_read_double") param.num_read_double_ = stoi(value); else if (key == "num_write_char") param.num_write_char_ = stoi(value); + else if (key == "max_len_float") param.max_len_float_ = stoi(value); + else if (key == "max_len_tmpname") param.max_len_tmpname_ = stoi(value); } file_param.close(); return true; diff --git a/src/param.h b/src/param.h index cc32af0..e93a1d4 100644 --- a/src/param.h +++ b/src/param.h @@ -1,4 +1,3 @@ -#pragma once #ifndef PARAM_H_ #define PARAM_H_ @@ -19,18 +18,17 @@ class Param{ int num_read_double_; int num_write_char_; - int max_num_file_; int max_len_float_; int max_len_tmpname_; int Print(const char* fmt = "config: %s=%s\n"); - + private: Param(): fpath_input_(""), fpath_output_(""), num_read_char_(100000000), num_sort_once_(17500000), num_read_double_(40000000), num_write_char_(200000000), - max_num_file_(1000), max_len_float_(100), max_len_tmpname_(100){}; + max_len_float_(100), max_len_tmpname_(100) {}; //Param(const Param&) {}; //Param& operator=(const Param&) {}; ~Param() {}; @@ -38,7 +36,7 @@ class Param{ bool ParseParam(const std::string& fpath); -bool IsFileExist(const std::string fpath); +bool IsFileExist(const std::string& fpath); #endif // !PARAM_H_ diff --git a/src/type_convert.h b/src/type_convert.h deleted file mode 100644 index 53c0dec..0000000 --- a/src/type_convert.h +++ /dev/null @@ -1,112 +0,0 @@ -#pragma once -#ifndef TYPE_CONVERT_H_ -#define TYPE_CONVERT_H_ - -//#ifdef DIVIDE_SORT -static double dpow[310], lpow[310]; -static int pw[5]; -//#endif - -#ifdef TYPE_CONVERT_INIT -int TypeConvertInit() { - dpow[0] = 1.0; - int i = 1; - for (i = 1; i < 309; ++i) dpow[i] = dpow[i - 1] * 0.1; - lpow[0] = 1.0L; - for (i = 1; i < 309; ++i) lpow[i] = lpow[i - 1] * 10.L; - pw[0] = 1; - for (i = 1; i < 4; ++i) pw[i] = pw[i - 1] * 10; - return 0; -} -#endif - -inline bool IsDigit(char c) { - if ((c - '0' > 9) || (c - '0' < 0)) return 0; - return 1; -} - -inline bool IsAlpha(char c) { - if ((c == 'e') || (c == 'E') || (c == '.')) return 1; - return 0; -} - -#ifdef DIVIDE_SORT - -// reference: http://www.leapsecond.com/tools/fast_atof.c -double FastCToF(char* c, int ep, int dotp) { - double fig = 0; - - int i = 0; - double sign = 1.0; //plus or minus - int signs = 1, expon = 0;//signs-index sign,expon-index - double scale = 1.0;//scale, 10 to the exponent - if (c[i] == '-') { - sign = -1.0; - i++; - } - if (c[i] == '+') { - i++; - } - - //has exponential bit - if (ep != -1) { - // base is not a decimal - if (dotp == -1) { - for (i; i < ep; i++) - fig = fig * 10.0 + (c[i] - '0'); - } - else { - //get integer part - //If . comes out front, fig=0 - for (i; i < dotp; i++) - fig = fig * 10.0 + (c[i] - '0'); - i++; - //get decimal part - for (i; i < ep; i++) - fig += (c[i] - '0') * dpow[i - dotp]; - } - fig *= sign; - - i++;// skip e or E - if (c[i] == '+') { - i++; - } - if (c[i] == '-') { - signs = -1.0; - i++; - } - //index part - for (i; IsDigit(c[i]); i++) - expon = expon * 10 + (c[i] - '0'); - - while (expon >= 200) { scale *= 1E200; expon -= 200; } - while (expon >= 80) { scale *= 1E80; expon -= 80; } - while (expon >= 30) { scale *= 1E30; expon -= 30; } - while (expon >= 12) { scale *= 1E12; expon -= 12; } - while (expon >= 5) { scale *= 1E5; expon -= 5; } - while (expon > 0) { scale *= 10.0; expon -= 1; } - - if (signs > 0) fig *= scale; - if (signs < 0) fig /= scale; - } - else { - // base is not a decimal - if (dotp == -1) { - for (i; IsDigit(c[i]); i++) - fig = fig * 10.0 + (c[i] - '0'); - } - else { - for (i; i < dotp; i++) - fig = fig * 10.0 + (c[i] - '0'); - i++; - for (i; IsDigit(c[i]); i++) - fig += (c[i] - '0') * dpow[i - dotp]; - } - fig *= sign; - } - return fig; -} - -#endif - -#endif // !TYPE_H_ diff --git a/test/example_sort.txt b/test/example_sort.txt index 6e88dc9..eec4c72 100644 --- a/test/example_sort.txt +++ b/test/example_sort.txt @@ -1,8 +1,10 @@ -1.838959550E+295 -4.461809619E+000 -6.618565698E-025 --0.000000000E-308 +0.000000000E+000 +0.000000000E+000 6.595810378E-307 1.465920800E+000 -5.000000000E+001 +5.999999999E+000 +8.000000000E+001 6.035090844E+015 diff --git a/test/example_unsort.txt b/test/example_unsort.txt index 50b48b4..adc01f8 100644 --- a/test/example_unsort.txt +++ b/test/example_unsort.txt @@ -1,10 +1,12 @@ 1.4659208 -0 +0.0 -0.6618565698E-24 4.9201e409E180 -1.8389595496E295 6.03509084408E15 H-2.4&1243#%$ 6.595810378E-307 -49.9999999995 +79.9999999995 -4.461809619 +5.999999999499