2017-04-17 80 views
0

我无法让我的函数正确返回变量。返回声明不能正确返回变量

我打印我想返回上面的返回语句的变量,它看起来很好。一旦我尝试返回值并将其打印到控制台上,但它会打印-nan(ind)。我不明白为什么会发生这种情况。

我用C++编程,使用Visual Studio。我使用这个库来解析字符串转换为表达式:http://www.partow.net/programming/exprtk/index.html

下面是函数和它打印结果的声明:

#include "stdafx.h" 
#include "exprtk.hpp" 
#include <iostream> 
#include <string> 
#include <algorithm> 
#include <cmath> 

typedef double T; // numeric type (float, double, mpfr etc...) 
typedef exprtk::expression<T>  expression_t; 
typedef exprtk::parser<T>    parser_t; 
expression_t expression; 
parser_t parser; 

bool closeEnough(std::string value1, std::string value2, double levelOfSimilarity) { 

    if (abs(std::stod(value1)) - abs (std::stod(value2)) > levelOfSimilarity) { 
     return false; 
    } 
    else { 
     return true; 
    } 
} 

std::string replaceChars2Strings(std::string string, const std::string& start, const std::string& end) { 

    size_t init_pos = 0; 

    while ((init_pos = string.find(start, init_pos)) != std::string::npos) { 
     string.replace(init_pos, start.length(), end); 
    } 
    return string; 
} 

double FofX(std::string function, std::string value) { 

    std::string newfunction = replaceChars2Strings(function, std::string("x"), value); 


    if (!parser.compile(newfunction, expression)) 
    { 
     printf("Something went wrong when the expression was being parsed"); 
    } 

    T result = expression.value(); 

    return result; 
} 

double DofFofX(std::string function, std::string value) { 

    std::string SDplus = replaceChars2Strings(function, std::string("x"), "(" + value + "+" + "0.00001" + ")"); 
    std::string SDminus = replaceChars2Strings(function, std::string("x"), "(" + value + "-" + "0.00001" + ")"); 

    if (!parser.compile(SDplus, expression)) 
    { 
     printf("Something went wrong when Dplus was being parsed"); 
    } 
    T Dplus = expression.value(); 

    if (!parser.compile(SDminus, expression)) 
    { 
     printf("Something went wrong when Dminus was being parsed"); 
    } 
    T Dminus = expression.value(); 

    return (Dplus - Dminus)/0.00002; 
} 

double newton(std::string function, std::string guess) { 
    double guess2; 
    //std::cout << "guess:" << guess << std::endl; 

    //in here() are taken off so that the compiler can calculate the value of guess 2 easier 
    guess2 = std::stod(guess.substr(1, guess.size() - 2)) - FofX(function, guess)/DofFofX(function, guess); 

    //std::cout << "guess 2:" << guess2 << std::endl; 

    //take the() off of guess before we give it away 
    if (closeEnough(guess.substr(1, guess.size() - 2), std::to_string(guess2), 0.001)) { 
     std::cout << "final guess = " << guess2 << std::endl; 
     return guess2; 
    } 
    else { 
     //put the() back on before we give it away so that the parser can read things as multiplication right 
     newton(function, "(" + std::to_string(guess2) + ")"); 
    } 
} 

int main() 
{ 
    std::string function = "x*x"; 
    //remember to put() around guess 
    std::string guess = "(5)"; 

    double answer = newton(function, guess); 

    return 0; 
} 

,当该程序运行时,它打印此:

final guess = 0.0006105 
solution = -nan(ind) 

有没有人知道我打印最终猜测和打印解决方案之间发生了什么?

+0

请给出一个完整的例子。如果不知道'FofX','DofFofX'和'closeEnough'是什么,就不可能知道发生了什么,充其量只会猜测。 – OmnipotentEntity

+0

一个小的评论,它被认为是不好的做法,有一个函数,以“非自然形式”(即不是该函数使用的最基本的形式)输入。在你的情况'牛顿'接受两个字符串参数,而(因为你用C++ 11标记了它),它应该更自然地采用一个函数,并返回一个double和一个double。您可以在else语句中看到这种尴尬,您必须重新修改该字符串才能将其传回给自己。 – OmnipotentEntity

+2

函数 –

回答

2

问题是我没有在我的else语句中返回递归函数。

最终的代码如下所示:

// Newtons Method V1.cpp : Defines the entry point for the console application. 
// 

#include "stdafx.h" 
#include "exprtk.hpp" 
#include <iostream> 
#include <string> 
#include <algorithm> 
#include <cmath> 

typedef double T; // numeric type (float, double, mpfr etc...) 
typedef exprtk::expression<T>  expression_t; 
typedef exprtk::parser<T>    parser_t; 
expression_t expression; 
parser_t parser; 

bool closeEnough(std::string value1, std::string value2, double levelOfSimilarity) { 

    if (abs(std::stod(value1)) - abs (std::stod(value2)) > levelOfSimilarity) { 
     return false; 
    } 
    else { 
     return true; 
    } 
} 

std::string replaceChars2Strings(std::string string, const std::string& start, const std::string& end) { 

    size_t init_pos = 0; 

    while ((init_pos = string.find(start, init_pos)) != std::string::npos) { 
     string.replace(init_pos, start.length(), end); 
    } 
    return string; 
} 

double FofX(std::string function, std::string value) { 

    std::string newfunction = replaceChars2Strings(function, std::string("x"), value); 


    if (!parser.compile(newfunction, expression)) 
    { 
     printf("Something went wrong when the expression was being parsed"); 
    } 

    T result = expression.value(); 

    return result; 
} 

double DofFofX(std::string function, std::string value) { 

    std::string SDplus = replaceChars2Strings(function, std::string("x"), "(" + value + "+" + "0.00001" + ")"); 
    std::string SDminus = replaceChars2Strings(function, std::string("x"), "(" + value + "-" + "0.00001" + ")"); 

    if (!parser.compile(SDplus, expression)) 
    { 
     printf("Something went wrong when Dplus was being parsed"); 
    } 
    T Dplus = expression.value(); 

    if (!parser.compile(SDminus, expression)) 
    { 
     printf("Something went wrong when Dminus was being parsed"); 
    } 
    T Dminus = expression.value(); 

    return (Dplus - Dminus)/0.00002; 
} 

double newton(std::string function, std::string guess) { 
    double guess2; 
    //std::cout << "guess:" << guess << std::endl; 

    //in here() are taken off so that the compiler can calculate the value of guess 2 easier 
    guess2 = std::stod(guess.substr(1, guess.size() - 2)) - FofX(function, guess)/DofFofX(function, guess); 

    //std::cout << "guess 2:" << guess2 << std::endl; 

    //take the() off of guess before we give it away 
    if (closeEnough(guess.substr(1, guess.size() - 2), std::to_string(guess2), 0.00001)) { 
     std::cout << "final guess = " << guess2 << std::endl; 
     return guess2; 
    } 
    else { 
     return newton(function, "(" + std::to_string(guess2) + ")"); 
    } 
} 

int main() 
{ 
    std::string function = "2^x - x^2"; 
    //remember to put() around guess 
    std::string guess = "(-2)"; 

    double answer = newton(function, guess); 
    std::cout << answer << std::endl; 

    return 0; 
}