diff --git a/CMakeLists.txt b/CMakeLists.txt index 74a38ae..f019d66 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,8 +4,9 @@ cmake_minimum_required(VERSION 2.6) project(rpn) -if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Release CACHE string "Choose the type of build, options are: None Debug Release" FORCE) +if((NOT CMAKE_BUILD_TYPE MATCHES Debug) + AND (NOT CMAKE_BUILD_TYPE MATCHES Release)) + set(CMAKE_BUILD_TYPE Release CACHE string "Choose the type of build, options are: None Debug Release" FORCE) endif() message(STATUS "Build mode: ${CMAKE_BUILD_TYPE}") @@ -22,11 +23,11 @@ set(RPN_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/README.md") # compiler options if(CMAKE_COMPILER_IS_GNUCXX) - message(STATUS "Compiler type GNU: ${CMAKE_CXX_COMPILER}") - set(BASE_COMPILER_OPTIONS "-std=c++0x -Wl,--no-as-needed") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${BASE_COMPILER_OPTIONS}") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${BASE_COMPILER_OPTIONS} -O0 -g") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${BASE_COMPILER_OPTIONS} -O3 -fomit-frame-pointer -s") + message(STATUS "Compiler type GNU: ${CMAKE_CXX_COMPILER}") + set(BASE_COMPILER_OPTIONS "-std=c++0x -Wl,--no-as-needed") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${BASE_COMPILER_OPTIONS}") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${BASE_COMPILER_OPTIONS} -O0 -g") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${BASE_COMPILER_OPTIONS} -O3 -fomit-frame-pointer -s") endif() # custom linenoise-ng diff --git a/src/object.cpp b/src/object.cpp index d9f4a73..c2ce86d 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -70,7 +70,7 @@ static bool is_min(mpfr_t p, mpfr_prec_t prec) return ret; } -static void print_fix(FILE* stream, mpfr_t real, int base) +static void print_fix(FILE* stream, mpfr_t real, int base, const char* write_after_sign = NULL) { // see mpfr_vasprintf code mpfr_exp_t exp = mpfr_get_exp(real); @@ -92,6 +92,8 @@ static void print_fix(FILE* stream, mpfr_t real, int base) // zero if (MPFR_IS_NEG(real)) fputc('-', stream);//signed zero is allowed + if (write_after_sign != NULL) + fputs(write_after_sign, stream); fputc('0', stream); if (digits > 0) { @@ -105,6 +107,8 @@ static void print_fix(FILE* stream, mpfr_t real, int base) { if (MPFR_IS_NEG(real)) fputc('-', stream); + if (write_after_sign != NULL) + fputs(write_after_sign, stream); fputc('0', stream); if (digits > 0) { @@ -121,22 +125,26 @@ static void print_fix(FILE* stream, mpfr_t real, int base) else { char* str = mpfr_get_str(NULL, &exp, base, digits + exp + 1, real, floating_t::s_mpfr_rnd); + char* print_from; if(str != NULL) { int len = strlen(str); + print_from = str; if (len > 0) { - if (str[0] == '-') + if (print_from[0] == '-') { - fputc(str[0], stream); + fputc(print_from[0], stream); len--; - str++; + print_from++; } - else if (str[0] == '+') + else if (print_from[0] == '+') { len--; - str++; + print_from++; } + if (write_after_sign != NULL) + fputs(write_after_sign, stream); if (exp < 0) { fputc('0', stream); @@ -156,14 +164,14 @@ static void print_fix(FILE* stream, mpfr_t real, int base) fputc('0', stream); else for (i = 0; i < (int)exp; i++) - fputc(str[i], stream); + fputc(print_from[i], stream); if (digits > 0) { fputc('.', stream); - int remaining = (int)MIN(strlen(str) - exp - 1, digits) + 1; + int remaining = (int)MIN(strlen(print_from) - exp - 1, digits) + 1; for (i = (int)exp; i < remaining + (int)exp; i++) - fputc(str[i], stream); + fputc(print_from[i], stream); for (i = 0; i < (int)(exp + digits - len); i++) fputc('0', stream); } @@ -178,6 +186,7 @@ void object::show(FILE* stream) { int digits; char* str; + char base[32]; switch(_type) { @@ -188,16 +197,14 @@ void object::show(FILE* stream) mpfr_fprintf(stream, number::s_mpfr_printf_format.c_str(), ((number*)this)->_value.mpfr); break; case number::hex: - fprintf(stream, "0x"); - print_fix(stream, ((number*)this)->_value.mpfr, 16); + print_fix(stream, ((number*)this)->_value.mpfr, 16, "0x"); break; case number::bin: - fprintf(stream, "0b"); - print_fix(stream, ((number*)this)->_value.mpfr, 2); + print_fix(stream, ((number*)this)->_value.mpfr, 2, "0b"); break; case number::base: - fprintf(stream, "%db", ((number*)this)->_base); - print_fix(stream, ((number*)this)->_value.mpfr, ((number*)this)->_base); + sprintf(base, "%db", ((number*)this)->_base); + print_fix(stream, ((number*)this)->_value.mpfr, ((number*)this)->_base, base); break; default: fprintf(stream, ""); diff --git a/test/11-base-entry.txt b/test/11-base-entry.txt index a2bc167..35caaee 100644 --- a/test/11-base-entry.txt +++ b/test/11-base-entry.txt @@ -164,3 +164,31 @@ del default 2345321 57 base dup 62 base == dec -> stack should be 1, 1, 1, 1 del default + +# negative base numbers (1) +1000 hex neg +-> stack should be -0x3e8 +del default + +# negative base numbers (2) +1000 7 base neg +-> stack should be -7b2626 +del default + +# negative base numbers (3) +1000 bin neg +-> stack should be -0b1111101000 +del default + +# negative base numbers (4) +-0b1111101000 3 base +-> stack should be -3b1101001 +del default + +# inf should not be based-represented +-1 bin 0 bin / 1 3 base 0 3 base / +-> stack should be -inf, inf + +# nan should not be based-represented +-0 bin 0 bin / 0 3 base 0 3 base / +-> stack should be nan, nan