From 95f4bb3e97bafda1ee04abd83ae8d16cab7bc76b Mon Sep 17 00:00:00 2001 From: PKEuS Date: Mon, 10 Sep 2012 21:13:32 +0200 Subject: [PATCH] Implemented support for binary numbers (#4113) --- lib/mathlib.cpp | 19 +++++++++++++++++++ lib/mathlib.h | 1 + lib/tokenlist.cpp | 2 +- test/testmathlib.cpp | 8 ++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/lib/mathlib.cpp b/lib/mathlib.cpp index 496260711..2d5555b34 100644 --- a/lib/mathlib.cpp +++ b/lib/mathlib.cpp @@ -45,6 +45,19 @@ MathLib::bigint MathLib::toLongNumber(const std::string &str) return ret; } + // binary numbers: + if (isBin(str)) { + bigint ret = 0; + for (std::string::size_type i = str[0] == '0'?2:3; i < str.length(); i++) { + ret <<= 1; + if (str[i] == '1') + ret |= 1; + } + if (str[0] == '-') + ret = -ret; + return ret; + } + if (str.find_first_of("eE") != std::string::npos) return static_cast(std::atof(str.c_str())); @@ -100,6 +113,12 @@ bool MathLib::isHex(const std::string& str) return(str.compare(sign?1:0, 2, "0x") == 0 || str.compare(sign?1:0, 2, "0X") == 0); } +bool MathLib::isBin(const std::string& str) +{ + bool sign = str[0]=='-' || str[0]=='+'; + return(str.compare(sign?1:0, 2, "0b") == 0 && str.find_first_not_of("10b", 1) == std::string::npos); +} + bool MathLib::isInt(const std::string & s) { // perform prechecks: diff --git a/lib/mathlib.h b/lib/mathlib.h index 4c5a551c2..6ce176f9d 100644 --- a/lib/mathlib.h +++ b/lib/mathlib.h @@ -51,6 +51,7 @@ public: static bool isNegative(const std::string &str); static bool isHex(const std::string& str); static bool isOct(const std::string& str); + static bool isBin(const std::string& str); static std::string add(const std::string & first, const std::string & second); static std::string subtract(const std::string & first, const std::string & second); diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index a761f0ff0..d2c9c4948 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -90,7 +90,7 @@ void TokenList::addtoken(const char str[], const unsigned int lineno, const unsi // Replace hexadecimal value with decimal std::ostringstream str2; - if (MathLib::isHex(str) || MathLib::isOct(str)) { + if (MathLib::isHex(str) || MathLib::isOct(str) || MathLib::isBin(str)) { str2 << MathLib::toLongNumber(str); } else if (strncmp(str, "_Bool", 5) == 0) { str2 << "bool"; diff --git a/test/testmathlib.cpp b/test/testmathlib.cpp index 6e31d45b6..3a8ba9022 100644 --- a/test/testmathlib.cpp +++ b/test/testmathlib.cpp @@ -164,6 +164,14 @@ private: ASSERT_EQUALS(125 , MathLib::toLongNumber("+0175")); ASSERT_EQUALS(-125 , MathLib::toLongNumber("-0175")); + // from binary + ASSERT_EQUALS(0 , MathLib::toLongNumber("0b0")); + ASSERT_EQUALS(1 , MathLib::toLongNumber("0b1")); + ASSERT_EQUALS(1 , MathLib::toLongNumber("+0b1")); + ASSERT_EQUALS(-1 , MathLib::toLongNumber("-0b1")); + ASSERT_EQUALS(215 , MathLib::toLongNumber("0b11010111")); + ASSERT_EQUALS(-215 , MathLib::toLongNumber("-0b11010111")); + // from base 10 ASSERT_EQUALS(10 , MathLib::toLongNumber("10")); ASSERT_EQUALS(10 , MathLib::toLongNumber("10."));