From e64cb84fe43660818f7d6eff2954147495b1ac8b Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Wed, 7 Jan 2015 09:53:14 -0700 Subject: Fixed parsing bug, added unit tests, debug cleanup. There was an issue with order of operations outside of parenthesies, easily solved. --- src/config.h | 2 +- src/main.cpp | 2 ++ src/number.cpp | 4 +-- src/number.h | 1 + src/options.cpp | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/options.h | 1 + src/parser.cpp | 1 + src/unitparser.cpp | 2 ++ 8 files changed, 110 insertions(+), 3 deletions(-) diff --git a/src/config.h b/src/config.h index a3f8b9e..f55be13 100644 --- a/src/config.h +++ b/src/config.h @@ -1,7 +1,7 @@ #ifndef CONFIG_H #define CONFIG_H -#define CLIC_VERSION "0.11" +#define CLIC_VERSION "0.12" #define CLIC_VERSION_STR "Clic v" CLIC_VERSION #define DEBUG_DIVIDE false diff --git a/src/main.cpp b/src/main.cpp index a1d7672..1a4ab38 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,6 +8,8 @@ #include #include +#include + #include #include using namespace Bu; diff --git a/src/number.cpp b/src/number.cpp index 05e310c..eb803be 100644 --- a/src/number.cpp +++ b/src/number.cpp @@ -662,11 +662,11 @@ Number Number::toRadix( int iNewRadix, int iNewScale ) const n.set( iNewRadix ); while( !me.isZero() ) { - Bu::println("%1 %% %2 = %3").arg( me ).arg( n ).arg( me%n ); +// Bu::println("%1 %% %2 = %3").arg( me ).arg( n ).arg( me%n ); int dig = (me%n).toInt32(); ret.aInt.append( dig ); me = me / n; - Bu::println("New digit: %1 (%2)").arg( dig ).arg( me ); +// Bu::println("New digit: %1 (%2)").arg( dig ).arg( me ); } return ret; diff --git a/src/number.h b/src/number.h index fe10788..2f7a583 100644 --- a/src/number.h +++ b/src/number.h @@ -49,6 +49,7 @@ public: int getScale() const { return iScale; } int getEffectiveScale() const; void setScale( int iNewScale ); + int getIntegralDigits() const { return aInt.getSize(); } int32_t toInt32() const; Number toRadix( int iNewRadix, int iNewScale=-1 ) const; diff --git a/src/options.cpp b/src/options.cpp index d88df3b..26f0cb7 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -39,6 +39,8 @@ Options::Options( int argc, char *argv[] ) : "your shell)."); addOption( Bu::slot(this, &Options::sum), "sum", "Read numbers from standard input and sum them, output the result."); + addOption( Bu::slot(this, &Options::grind), 'g', "grind", + "Search for magic numbers. Secret magic numbers."); addOption( Bu::slot(this, &Options::version), 'v', "version", "Show the version string ('" CLIC_VERSION_STR "')"); addHelpOption('h', "help", "This help"); @@ -224,3 +226,101 @@ int Options::version( Bu::StringArray aArgs ) return 0; } +bool onlyNines( const Bu::String &s ) +{ + for( Bu::String::const_iterator i = s.begin(); i; i++ ) + { + if( *i != '9' ) + return false; + } + return true; +} + +bool onlyOnes( const Bu::String &s ) +{ + for( Bu::String::const_iterator i = s.begin(); i; i++ ) + { + if( *i != '1' ) + return false; + } + return true; +} + +int Options::grind( Bu::StringArray aArgs ) +{ + Number test("1"); + Number bit("1"); + Number mult("2"); + int64_t iBits = 1; + int iLastSize = 0; + + if( aArgs.getSize() > 1 ) + { + Bu::print("Loading number..."); Bu::sioRaw.flush(); + Bu::String num = Bu::File(aArgs[1], Bu::File::Read).readAll(); + test = num; + Bu::println("done."); + Bu::print("Computing bit..."); Bu::sioRaw.flush(); + bit = test; + bit = bit+Number("1"); + bit = bit/mult; + Bu::println("done."); + if( aArgs.getSize() > 2 ) + { + Bu::print("Trusting a human for where we are..."); Bu::sioRaw.flush(); + iBits = strtoll( aArgs[2].getStr(), NULL, 10 ); + } + else + { + Bu::print("Figuring out where we are..."); Bu::sioRaw.flush(); + Bu::String sBin = bit.toRadix(2).toString(); + iBits = sBin.getSize(); + } +// Bu::println("Done. Checking."); +// Bu::println("test = %1, bit = %2").arg( test ).arg( bit ); +// Bu::String sTest = test.toRadix(2).toString(); +// Bu::File("check-bit.txt", Bu::File::WriteNew ).write( sBin ); +// Bu::File("check-test.txt", Bu::File::WriteNew ).write( sTest ); + iLastSize = num.getSize(); +// Bu::println("File written. %1 bits").arg( sBin.getSize() ); + Bu::println("done."); + Bu::println("Continuing calculation..."); + } + + for(;;) + { + bit = bit*mult; + test = test + bit; + Bu::String r = test.toString(); + iBits++; + + if( onlyNines(r) ) + { + Bu::println("%1 digits").arg( r.getSize() ); + Bu::File f("answer-dec.txt", Bu::File::WriteNew ); + f.write( r ); + Bu::println("Success."); +// Bu::println("%1 == %2").arg( test.toRadix(2) ).arg( r ); + return 0; + } + if( r.getSize() != iLastSize && r.getSize()%1000 == 0 ) + { + /* + Bu::String rs = test.toRadix(2).toString(); + int iOBits = rs.getSize(); + if( iOBits != iBits ) + Bu::println("Bit mismatch: %1 vs %2").arg( iOBits ).arg( iBits ); + if( !onlyOnes( rs ) ) + Bu::println("Not only ones!"); + */ + iLastSize = r.getSize(); + Bu::println("%1 digits").arg( r.getSize() ); + Bu::File f(Bu::String("interum-%1-%2.txt").arg( r.getSize() ).arg( iBits ), Bu::File::WriteNew ); + f.write( r ); + } + } + Bu::println("Failure."); + exit( 0 ); + return 0; +} + diff --git a/src/options.h b/src/options.h index f3f59a6..a7453ab 100644 --- a/src/options.h +++ b/src/options.h @@ -20,6 +20,7 @@ private: int execute( Bu::StringArray aArgs ); int sum( Bu::StringArray aArgs ); int version( Bu::StringArray aArgs ); + int grind( Bu::StringArray aArgs ); int iScale; int iRadix; diff --git a/src/parser.cpp b/src/parser.cpp index bd49c38..153b6fe 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -270,6 +270,7 @@ void Parser::unwind() { tsNonTerminal.pop(); + unwind(); } else { diff --git a/src/unitparser.cpp b/src/unitparser.cpp index e23f76c..f518fdc 100644 --- a/src/unitparser.cpp +++ b/src/unitparser.cpp @@ -38,6 +38,8 @@ void UnitParser::order1() unitTest(parse("1.59*40/24*21", 5) == "55.65"); unitTest(parse("1.59*40/(24*21)", 5) == "0.12619"); // bc says it's this: "0.12619"); unitTest(parse("10+2*2*2+2") == "20"); + unitTest(parse("5-5-1") == "-1"); + unitTest(parse("5-(1+2+2)-1") == "-1"); } void UnitParser::assignment() -- cgit v1.2.3 From f03026f5c2cde1eecfda273eaa52df10287f0f9e Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Thu, 29 Jan 2015 08:49:55 -0700 Subject: Fixed nasty subtraction bug when dealing with fractions. It turned out to be a really simple solution, but man, that was embarassing. I forgot to include the fractional portion of a number when fixing my radix+1 compliment numbers. --- src/config.h | 3 ++- src/number.cpp | 59 ++++++++++++++++++++++++++++++++++++------------------ src/number.h | 1 + src/unitnumber.cpp | 12 +++++++---- src/unitnumber.h | 1 + 5 files changed, 52 insertions(+), 24 deletions(-) diff --git a/src/config.h b/src/config.h index f55be13..482ef9e 100644 --- a/src/config.h +++ b/src/config.h @@ -1,11 +1,12 @@ #ifndef CONFIG_H #define CONFIG_H -#define CLIC_VERSION "0.12" +#define CLIC_VERSION "0.13" #define CLIC_VERSION_STR "Clic v" CLIC_VERSION #define DEBUG_DIVIDE false #define DEBUG_PARSE false +#define DEBUG_ADD false #define DBS( s, x ) if( DEBUG_ ##s ) { x; } (void)0 #define DBS_START( s ) if( DEBUG_ ##s ) { (void)0 diff --git a/src/number.cpp b/src/number.cpp index eb803be..660ba61 100644 --- a/src/number.cpp +++ b/src/number.cpp @@ -610,6 +610,19 @@ int Number::digit( int iIdx ) const return aInt[iIdx]; } +void Number::setDigit( int iIdx, int iVal ) +{ + if( iIdx < 0 ) + { + if( iIdx >= -iScale ) + aFrac.set( -1-iIdx, iVal ); + return; + } + if( iIdx >= aInt.getSize() ) + return; + aInt.set( iIdx, iVal ); +} + void Number::setScale( int iNewScale ) { if( iNewScale == 0 ) @@ -680,7 +693,7 @@ Number Number::add( const Number &rhs, bool bSub ) const int iZeros = 0; int iCarry = 0; -// Bu::println("::: %1 + %2:").arg( toString() ).arg( rhs.toString() ); + DBS( ADD, Bu::println("::: %1 + %2:").arg( toString() ).arg( rhs.toString() ) ); if( bPositive == (bSub?!rhs.bPositive:rhs.bPositive)) { @@ -688,9 +701,10 @@ Number Number::add( const Number &rhs, bool bSub ) const for( int j = -iScale; j < iPlaces || iCarry > 0; j++ ) { int iRes = iCarry + digit( j ) + rhs.digit( j ); -// Bu::println(" [%5] Place: %1 + %2 + (%3) = %4"). -// arg( digit(j) ).arg( rhs.digit( j ) ).arg( iCarry ) -// .arg( iRes ).arg( j ); + DBS( ADD, + Bu::println(" [%5] Place: %1 + %2 + (%3) = %4"). + arg( digit(j) ).arg( rhs.digit( j ) ).arg( iCarry ) + .arg( iRes ).arg( j ) ); if( j < 0 ) ret.aFrac.set( -1-j, (iRes%iRadix) ); else @@ -714,16 +728,25 @@ Number Number::add( const Number &rhs, bool bSub ) const else { iCarry = 1; -// Bu::println("--method b--"); + DBS( ADD, Bu::println("--method b--") ); ret.bPositive = bPositive; int iRes; int iComp = (iRadix-1); + for( int j = -iScale; j < iPlaces; j++ ) { iRes = digit( j ) + (iComp-rhs.digit( j )) + iCarry; -// Bu::println(" Place: %1 + %2 + (%3) = %4"). -// arg( digit(j) ).arg( 9-rhs.digit( j ) ).arg( iCarry ) -// .arg( iRes ); + if( iRes < iRadix ) + { + iCarry = 0; + } + else + iCarry = iRes/iRadix; + + DBS( ADD, + Bu::println(" Place: %1 + %2 + (%3) = %4"). + arg( digit(j) ).arg( iComp-rhs.digit( j ) ).arg( iCarry ) + .arg( iRes ) ); if( j < 0 ) ret.aFrac.set( -1-j, (iRes%iRadix) ); else @@ -738,24 +761,22 @@ Number Number::add( const Number &rhs, bool bSub ) const ret.aInt.append( (iRes%iRadix) ); } - if( iRes < iRadix ) - iCarry = 0; - else - iCarry = iRes/iRadix; } if( iCarry == 0 ) { ret.bPositive = false; - ret.aInt.set( 0, iComp-ret.aInt.get( 0 )+1); - for( int j = 1; j < ret.aInt.getSize(); j++ ) + int iVal = iComp-ret.digit( -ret.iScale )+1; + iCarry = (iVal >= iRadix) ? 1 : 0; + ret.setDigit( -ret.iScale, iVal%iRadix ); + + for( int j = -iScale+1; j < ret.aInt.getSize(); j++ ) { - ret.aInt.set( j, iComp-ret.aInt.get( j )); + iVal = iComp-ret.digit( j )+iCarry; + iCarry = (iVal >= iRadix) ? 1 : 0; + ret.setDigit( j, iVal%iRadix ); } } - else - { - ret.aInt.trim(); - } + ret.aInt.trim(); } return ret; diff --git a/src/number.h b/src/number.h index 2f7a583..79cd5f5 100644 --- a/src/number.h +++ b/src/number.h @@ -45,6 +45,7 @@ public: Bu::String toString() const; int digit( int iIdx ) const; + void setDigit( int iIdx, int iVal ); int getScale() const { return iScale; } int getEffectiveScale() const; diff --git a/src/unitnumber.cpp b/src/unitnumber.cpp index 985f0d9..d213ed7 100644 --- a/src/unitnumber.cpp +++ b/src/unitnumber.cpp @@ -136,13 +136,17 @@ void UnitNumber::number1() #define mathTest( anum, op, bnum, scale, answ ) \ unitTest( (Number(anum, scale) op Number(bnum, scale)).toString() == answ ) -/* + void UnitNumber::number2() { - mathTest( "1", /, "17", 10, "0.0588235294" ); - mathTest( "1", /, "177", 10, "0.0056497175" ); + mathTest("55", +, "-100", 0, "-45"); + mathTest("30.01", +, "-31.21", 2, "-1.20"); + mathTest("55", -, "100", 0, "-45"); + mathTest("30.01", -, "31.21", 2, "-1.20"); +// mathTest( "1", /, "17", 10, "0.0588235294" ); +// mathTest( "1", /, "177", 10, "0.0056497175" ); } -*/ + /* // clic diff --git a/src/unitnumber.h b/src/unitnumber.h index 96d882e..097fd5b 100644 --- a/src/unitnumber.h +++ b/src/unitnumber.h @@ -14,6 +14,7 @@ public: void multiply1(); void divide1(); void number1(); + void number2(); void compare1(); void radix1(); void fraction1(); -- cgit v1.2.3