+added a replacement real number formatting function; +added a replacement function of strtod on the wiki page.

This commit is contained in:
Wang Renxin 2017-02-03 15:34:30 +08:00
parent 747b608f58
commit 9c896d30bf
4 changed files with 59 additions and 0 deletions

View File

@ -1,3 +1,7 @@
Feb. 3 2017
Added a replacement real number formatting function
Added a replacement function of strtod on the wiki page, thanks to Paul Johnson for providing the code
Jan. 19 2017 Jan. 19 2017
Fixed a crash bug with unmatched ENDIF statement, thanks to yukini3 for pointing it out Fixed a crash bug with unmatched ENDIF statement, thanks to yukini3 for pointing it out

View File

@ -174,6 +174,7 @@ The [MY-BASIC Quick Reference](MY-BASIC%20Quick%20Reference.pdf) includes most o
* [Customize a memory allocator](https://github.com/paladin-t/my_basic/wiki/Customize-a-memory-allocator) * [Customize a memory allocator](https://github.com/paladin-t/my_basic/wiki/Customize-a-memory-allocator)
* [Redirect PRINT and INPUT](https://github.com/paladin-t/my_basic/wiki/Redirect-PRINT-and-INPUT) * [Redirect PRINT and INPUT](https://github.com/paladin-t/my_basic/wiki/Redirect-PRINT-and-INPUT)
* [Redefine int_t and real_t](https://github.com/paladin-t/my_basic/wiki/Redefine-int_t-and-real_t) * [Redefine int_t and real_t](https://github.com/paladin-t/my_basic/wiki/Redefine-int_t-and-real_t)
* [Convert between string and real](https://github.com/paladin-t/my_basic/wiki/Convert-between-string-and-real)
* [Customize an importer](https://github.com/paladin-t/my_basic/wiki/Customize-an-importer) * [Customize an importer](https://github.com/paladin-t/my_basic/wiki/Customize-an-importer)
* [More scripting APIs](https://github.com/paladin-t/my_basic/wiki/More-scripting-APIs) * [More scripting APIs](https://github.com/paladin-t/my_basic/wiki/More-scripting-APIs)
* [String matching module](https://github.com/paladin-t/my_basic/wiki/String-matching-module) * [String matching module](https://github.com/paladin-t/my_basic/wiki/String-matching-module)

View File

@ -35,6 +35,9 @@
# ifndef MB_DISABLE_LOAD_FILE # ifndef MB_DISABLE_LOAD_FILE
# define MB_DISABLE_LOAD_FILE # define MB_DISABLE_LOAD_FILE
# endif /* MB_DISABLE_LOAD_FILE */ # endif /* MB_DISABLE_LOAD_FILE */
# ifndef MB_MANUAL_REAL_FORMATTING
# define MB_MANUAL_REAL_FORMATTING
# endif /* MB_MANUAL_REAL_FORMATTING */
#endif /* ARDUINO && !MB_CP_ARDUINO */ #endif /* ARDUINO && !MB_CP_ARDUINO */
#ifdef MB_CP_VC #ifdef MB_CP_VC
# include <conio.h> # include <conio.h>
@ -1427,6 +1430,9 @@ static bool_t _try_get_value(_object_t* obj, mb_value_u* val, _data_e expected);
static bool_t _is_number(void* obj); static bool_t _is_number(void* obj);
static bool_t _is_string(void* obj); static bool_t _is_string(void* obj);
static char* _extract_string(_object_t* obj); static char* _extract_string(_object_t* obj);
#ifdef MB_MANUAL_REAL_FORMATTING
static void _real_to_str(real_t r, char* str, size_t size, size_t afterpoint);
#endif /* MB_MANUAL_REAL_FORMATTING */
#ifdef MB_ENABLE_COLLECTION_LIB #ifdef MB_ENABLE_COLLECTION_LIB
# define _IS_LIST(__o) ((__o) && ((_object_t*)(__o))->type == _DT_LIST) # define _IS_LIST(__o) ((__o) && ((_object_t*)(__o))->type == _DT_LIST)
@ -5841,6 +5847,40 @@ static char* _extract_string(_object_t* obj) {
return result; return result;
} }
#ifdef MB_MANUAL_REAL_FORMATTING
/* Convert a real number to string */
static void _real_to_str(real_t r, char* str, size_t size, size_t afterpoint) {
size_t pos = 0;
size_t len = 0;
char curr[4];
int val = (int)r;
char dot = 0;
itoa(val, str, 10);
if(r < 0) {
r *= -1;
val *= -1;
}
pos = len = strlen(str);
while(pos < size - 1) {
r = r - (real_t)val;
if(r == 0.0)
break;
if(!dot) {
dot = 1;
str[pos++] = '.';
}
r *= 10;
val = (int)r;
itoa(val, curr, 10);
str[pos++] = *curr;
if(--afterpoint == 0)
break;
}
str[pos] = '\0';
}
#endif /* MB_MANUAL_REAL_FORMATTING */
#ifdef _HAS_REF_OBJ_LOCK #ifdef _HAS_REF_OBJ_LOCK
/* Lock a referenced object */ /* Lock a referenced object */
static bool_t _lock_ref_object(_lock_t* lk, _ref_t* ref, void* obj) { static bool_t _lock_ref_object(_lock_t* lk, _ref_t* ref, void* obj) {
@ -15765,9 +15805,13 @@ static int _std_str(mb_interpreter_t* s, void** l) {
case MB_DT_REAL: case MB_DT_REAL:
lbuf = 1 /* - */ + (DBL_MAX_10_EXP + 1) /* 308 + 1 digits */ + 1 /* . */ + 6 /* precision */ + 1 /* \0 */; lbuf = 1 /* - */ + (DBL_MAX_10_EXP + 1) /* 308 + 1 digits */ + 1 /* . */ + 6 /* precision */ + 1 /* \0 */;
_RESIZE_CHAR_BUF(buf, lbuf); _RESIZE_CHAR_BUF(buf, lbuf);
#ifdef MB_MANUAL_REAL_FORMATTING
_real_to_str(arg.value.float_point, _CHAR_BUF_PTR(buf), lbuf, 5);
#else /* MB_MANUAL_REAL_FORMATTING */
if((size_t)sprintf(_CHAR_BUF_PTR(buf), MB_REAL_FMT, arg.value.float_point) >= lbuf) { if((size_t)sprintf(_CHAR_BUF_PTR(buf), MB_REAL_FMT, arg.value.float_point) >= lbuf) {
mb_assert(0 && "Buffer overflow."); mb_assert(0 && "Buffer overflow.");
} }
#endif /* MB_MANUAL_REAL_FORMATTING */
break; break;
#ifdef MB_ENABLE_CLASS #ifdef MB_ENABLE_CLASS
@ -16216,7 +16260,17 @@ _print:
} else if(val_ptr->type == _DT_INT) { } else if(val_ptr->type == _DT_INT) {
_get_printer(s)(MB_INT_FMT, val_ptr->data.integer); _get_printer(s)(MB_INT_FMT, val_ptr->data.integer);
} else if(val_ptr->type == _DT_REAL) { } else if(val_ptr->type == _DT_REAL) {
#ifdef MB_MANUAL_REAL_FORMATTING
_dynamic_buffer_t buf;
size_t lbuf = 32;
_INIT_BUF(buf);
_RESIZE_CHAR_BUF(buf, lbuf);
_real_to_str(val_ptr->data.float_point, _CHAR_BUF_PTR(buf), lbuf, 5);
_get_printer(s)("%s", _CHAR_BUF_PTR(buf));
_DISPOSE_BUF(buf);
#else /* MB_MANUAL_REAL_FORMATTING */
_get_printer(s)(MB_REAL_FMT, val_ptr->data.float_point); _get_printer(s)(MB_REAL_FMT, val_ptr->data.float_point);
#endif /* MB_MANUAL_REAL_FORMATTING */
} else if(val_ptr->type == _DT_STRING) { } else if(val_ptr->type == _DT_STRING) {
_print_string(s, val_ptr); _print_string(s, val_ptr);
if(!val_ptr->ref && val_ptr->data.string && !pathed_str) { if(!val_ptr->ref && val_ptr->data.string && !pathed_str) {

Binary file not shown.