diff --git a/.gitignore b/.gitignore index 0cf5766..43d84a3 100644 --- a/.gitignore +++ b/.gitignore @@ -13,9 +13,9 @@ *.a # Build dir -build* -debug_build -release_build +/build* +/debug_build +/release_build /bin /lib /install diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..23b9a3a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,47 @@ +cmake_minimum_required (VERSION 2.6) +project(tutorial) +set (tutorial_VERSION_MAJOR 1) +set (tutorial_VERSION_MINOR 0) + +option (USE_MYMATH "Use tutorial provided math implementation" ON) + +include (CheckFunctionExists) +set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} "-lm") +check_function_exists (log HAVE_LOG) +check_function_exists (exp HAVE_EXP) + +configure_file ( + "${PROJECT_SOURCE_DIR}/tutorial_config.h.in" + "${PROJECT_BINARY_DIR}/tutorial_config.h" +) + +include_directories("${PROJECT_BINARY_DIR}") + +add_executable(tutorial tutorial.cpp) +install (TARGETS tutorial DESTINATION bin) +install (FILES "${PROJECT_BINARY_DIR}/tutorial_config.h" DESTINATION include) + +if (USE_MYMATH) + include_directories ("${PROJECT_SOURCE_DIR}/mathfunctions") + add_subdirectory(mathfunctions) + set (EXTRA_LIBS ${EXTRA_LIBS} mathfunctions) +endif (USE_MYMATH) + +target_link_libraries(tutorial ${EXTRA_LIBS}) + +include(CTest) +add_test (TutorialRuns tutorial 25) + +macro (do_test arg result) + add_test (TutorialComp${arg} tutorial ${arg}) + set_tests_properties(TutorialComp${arg} PROPERTIES PASS_REGULAR_EXPRESSION ${result}) +endmacro (do_test) + +do_test(25 "25 is 5") +do_test(-25 "-25 is -nan") +do_test(0.0001 "0\\\\.0001 is 0\\\\.01") + +add_test (TutorialUsage tutorial) +set_tests_properties (TutorialUsage PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number") + + diff --git a/mathfunctions/CMakeLists.txt b/mathfunctions/CMakeLists.txt new file mode 100644 index 0000000..e38e7bb --- /dev/null +++ b/mathfunctions/CMakeLists.txt @@ -0,0 +1,11 @@ +add_executable(maketable maketable.cpp) + +add_custom_command ( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/table.h + COMMAND maketable ${CMAKE_CURRENT_BINARY_DIR}/table.h + DEPENDS maketable +) + +include_directories( ${CMAKE_CURRENT_BINARY_DIR} ) +add_library(mathfunctions mysqrt.cpp ${CMAKE_CURRENT_BINARY_DIR}/table.h ) +install (FILES mathfunctions.h DESTINATION include) diff --git a/mathfunctions/maketable.cpp b/mathfunctions/maketable.cpp new file mode 100644 index 0000000..0bb33ea --- /dev/null +++ b/mathfunctions/maketable.cpp @@ -0,0 +1,23 @@ +#include +#include +#include +#include + +int main(int argc, char **argv) { + int i; + double result; + + if (argc < 2) { + return 1; + } + + std::ofstream fout; + fout.open(argv[1]); + fout << "double sqrtTable[] = {" << std::endl; + for(int i = 0; i < 10; ++i) { + fout << sqrt(static_cast(i)) << "," << std::endl; + } + fout << "0};" << std::endl; + fout.close(); + return 0; +} diff --git a/mathfunctions/mathfunctions.h b/mathfunctions/mathfunctions.h new file mode 100644 index 0000000..7545289 --- /dev/null +++ b/mathfunctions/mathfunctions.h @@ -0,0 +1,4 @@ +#include +#include + +double mysqrt(double); diff --git a/mathfunctions/mysqrt.cpp b/mathfunctions/mysqrt.cpp new file mode 100644 index 0000000..f76d6fd --- /dev/null +++ b/mathfunctions/mysqrt.cpp @@ -0,0 +1,35 @@ +#include "mathfunctions.h" +#include "tutorial_config.h" +#include "table.h" +#include + +double improve(double guess, double x) { + double newguess = x / guess; + return (newguess + guess) / 2; +} + +bool goodenough(double guess, double x) { + return abs((guess * guess) - x) < 0.00000001; +} + +double mysqrt(double x) { + if (x < 10) { + std::cerr << "Using Table" << std::endl; + return sqrtTable[static_cast(x)]; + } + +#if defined (HAVE_LOG) && defined(HAVE_EXP) + std::cerr << "USING LOG" << std::endl; + return exp(log(x) * 0.5); +#else + double guess = 1.0; + double t = x; + while(1) { + if (goodenough(guess, t)) { + return guess; + } + guess = improve(guess, t); + } +#endif +} + diff --git a/tutorial.cpp b/tutorial.cpp new file mode 100644 index 0000000..dc4a202 --- /dev/null +++ b/tutorial.cpp @@ -0,0 +1,28 @@ +#include +#include +#include +#include "tutorial_config.h" +#ifdef USE_MYMATH +#include "mathfunctions.h" +#endif + + +int main(int argc, char **argv) { + if (argc < 2) { + std::cerr << argv[0] << " version " << tutorial_VERSION_MAJOR + << "." << tutorial_VERSION_MINOR << std::endl; + std::cerr << "Usage: " << argv[0] << " number\n"; + return 1; + } + + double inputvalue = atof(argv[1]); +#ifdef USE_MYMATH + std::cerr << "Using MYMATH" << std::endl; + double outputvalue = mysqrt(inputvalue); +#else + std::cerr << "Using sqrt" << std::endl; + double outputvalue = sqrt(inputvalue); +#endif + std::cout << "THe square root of " << inputvalue << " is " << outputvalue << std::endl; + return 0; +} diff --git a/tutorial_config.h.in b/tutorial_config.h.in new file mode 100644 index 0000000..bad34c8 --- /dev/null +++ b/tutorial_config.h.in @@ -0,0 +1,5 @@ +#cmakedefine USE_MYMATH +#define tutorial_VERSION_MAJOR @tutorial_VERSION_MAJOR@ +#define tutorial_VERSION_MINOR @tutorial_VERSION_MINOR@ +#cmakedefine HAVE_LOG +#cmakedefine HAVE_EXP