当等式返回nan作为答案时该怎么办?

时间:2013-10-10 18:48:14

标签: c++ overflow stack-overflow nan modulus

我的程序遇到了一些问题,我正在尝试为用户开发一种模拟密码可能优势的方法。这假设所有密码都是排列(我知道很奇怪,但我认为这是为了阻止数据变得更加笨拙。)使用等式......

// N!/(N-R)!当n! =(e ^ -n)*(n ^ n)sqrt(2(pi)n)。当n是使用中的字符数且r是密码长度时

无论我放什么,我都会收到nan作为答案。我想也许我的等式可能已关闭(也许某种程度上我将其除以零)所以我重新设计了它并简化了它。但这似乎不是问题,尽管我觉得这让我更接近正确。但我想到数字溢出可能会产生影响吗?但我真的不知道如何解决这样的问题。我尝试从不同的数据类型跳转,但似乎没有任何工作。

我的模数也有问题。它返回的数字小于零的时间,所以我的noobish知识告诉我,可能我再次溢出它但我怎么样才能使用%而不将它定义为int?也许修复上述问题会解决这个问题吗?

对于给予我的任何帮助,我都会感激不尽。如何处理纳米的回报值?是否有逐步解决问题的现状?它几乎总是溢出或者它可能是别的吗?

代码本身。

#include <iostream>
#include <cmath>

using namespace std;

const int SECONDS_IN_YEAR = 31556926;
const int SECONDS_IN_DAY  = 86400;
const int SECONDS_IN_HOUR = 3600;
const int SECONDS_IN_MIN  = 60;

int main()
{

    int passwordLength ,characterSymbols;
    double instructionsPerSecond, instructionSuccess;

    ////////////////////////////////////////////////////////////////////////////////
    //Equations needed
    // n!/(n-r)!
    //n is the number of letters in the alphabet
    //and r is the number of letters in the password

    // n! = (e^-n)*(n^n) sqrt(2(pi)n)
    double numeratorFactorial  = (pow(M_E,-characterSymbols))
                                *(pow(characterSymbols,characterSymbols))
                                *(sqrt(2*M_PI*characterSymbols));
    // (n-r)
    double characterMinusLength= (characterSymbols-passwordLength);

    // (n-r)! = (e^-(n-r)) * ((n-r)^(n-r)) * sqrt(2(pi)(n-r))
    double denominatorFactorial = ((pow(M_E, -(characterMinusLength)))*
                                (pow((characterMinusLength),(characterMinusLength)))
                                * (sqrt(2*M_PI*(characterMinusLength))));

    // n!/(n-r)!
    long double passwordPermutation = (numeratorFactorial / denominatorFactorial);

    // (passwords)* (instructions/Password) * (seconds/instruction) = sec
    int passwordSeconds = (passwordPermutation * instructionSuccess)
                         *(1/instructionsPerSecond);



    int passwordMin  = passwordSeconds / SECONDS_IN_MIN ;
    int passwordHour = passwordSeconds / SECONDS_IN_HOUR;
    int passwordDay  = passwordSeconds / SECONDS_IN_DAY ;
    int passwordYear = passwordSeconds / SECONDS_IN_YEAR;


    ////////////////////////////////////////////////////////////////////////////////
    //Explain purpose of program
    cout << "This program is designed to simulate the strength of passwords." << endl;

    //Ask for alphabet
    cout << "But first, share with me the max number of characters you'd be using."
         << endl;
    cin >> characterSymbols;
    //Reflect information
    cout << "We will be using " << characterSymbols << " character symbols to "
         << " construct the password.\n" << endl;



    ///////////////////////////////////////////////////////////////////////////////
    //Input length of password
    cout << "\n\nWill you give me the length of proposed password?" << endl;
    cin >> passwordLength;

    //Repeat information
    cout << "The password length will be " << passwordLength << "." <<endl;



    //cout permutations
    cout << "This would lead to " << passwordPermutation << " unique password\n"
         << endl;



    ////////////////////////////////////////////////////////////////////////////////
    //Ask for computer strength
    cout << "How powerful is this computer? How many instructions per second " << endl;
    cout << "can it accomplish?" << endl;
    cin >> instructionsPerSecond;

    //Read out computer strength
    cout << "The computer can do " << instructionsPerSecond << " instructions/second"
         << endl << endl;



    ////////////////////////////////////////////////////////////////////////////////

    //Ask for instructions/password
    cout << "The number of instructions needed to test your password is." << endl
         << endl;
    cin >> instructionSuccess;

    //reflect
    cout << "This computer can do " << instructionSuccess
     << " instructions/password" << endl;


    ////////////////////////////////////////////////////////////////////////////////
    cout << "\n\nThe amount of seconds it'll take to crack this passcode is... "
         << endl << passwordSeconds << " seconds.\n\n\n\n\n" << endl;

    ////////////////////////////////////////////////////////////////////////////////
    //Reflect all information in an easily readable table
    cout << "Number of character symbols using... " << characterSymbols      << endl;
    cout << "Length of password... "                << passwordLength        << endl;
    cout << "Number of permutations... "            << passwordPermutation   << endl;
    cout << "Instructions per second... "           << instructionsPerSecond << endl;
    cout << "Instructions per password..."          << instructionSuccess    << endl;

    cout << endl << endl << endl;

    ////////////////////////////////////////////////////////////////////////////////
    //Add in conversions for min, hour, day, years
    cout << "Number of seconds to break..." << passwordSeconds << endl;


    cout << "Converted to minutes..."       << passwordMin     << endl;
    passwordMin = passwordSeconds / SECONDS_IN_MIN;
    passwordSeconds = passwordSeconds % SECONDS_IN_MIN;

    cout << "Converted to hours..."         << passwordHour    << endl;
    passwordHour = passwordSeconds / SECONDS_IN_HOUR;
    passwordSeconds = passwordSeconds % SECONDS_IN_MIN;

    cout << "Converted to days..."          << passwordDay     << endl;
    passwordDay = passwordSeconds / SECONDS_IN_DAY;
    passwordSeconds = passwordSeconds % SECONDS_IN_DAY;

    cout << "Converted to years..."         << passwordYear    << endl;
    passwordYear = passwordSeconds / SECONDS_IN_YEAR;
    passwordSeconds = passwordSeconds % SECONDS_IN_YEAR;

    return (0);
}

2 个答案:

答案 0 :(得分:2)

“nan”代表“不是数字”。发生这种情况是因为您已声明变量characterSymbols和passwordLength而未给它们初始值。

您必须在使用之前初始化任何变量 - 如果不这样做,那么您将拥有未确定的行为。例如:

int x;
int y;
int z = x + y;

没有办法预测z在这里等于什么,因为我们不知道x或y等于什么。以同样的方式,您的代码应该是:

int characterSymbols = 10;  //or whatever you want the initial value to be

...

double numeratorFactorial  = (pow(M_E,-characterSymbols))
                            *(pow(characterSymbols,characterSymbols))
                            *(sqrt(2*M_PI*characterSymbols));

通过这种方式,numeratorFactorial将具有有效值。

答案 1 :(得分:0)

在您实际声明变量时,似乎您认为正在声明“方程式”。你写道:

double numeratorFactorial  = (pow(M_E,-characterSymbols))
                            *(pow(characterSymbols,characterSymbols))
                            *(sqrt(2*M_PI*characterSymbols));

characterSymbols未定义,仅“声明”。 characterSymbols在它上面声明,但它没有值......稍后您使用cin来获取值,但是当您第一次声明numeratorFactorial时,您不能简单地期望程序在numeratorFactorial时将值插入characterSymbols变化。

某些定义可能是有序的:语句double numeratorFactorial = some_value;创建一个名为numeratorFactorial的变量,并使用some_value立即填充该变量。你想要的是一个函数,一个逻辑语句,你可以“传递值”,所以当你需要它们时会生成值。例如,对于你的分子阶乘:

double numeratorFactorial(double characterSymbols) {
    return  (pow(M_E,-characterSymbols))
           *(pow(characterSymbols,characterSymbols))
           *(sqrt(2*M_PI*characterSymbols));
}

int main() {
    std::cout << "Numerator Factorial test: " << numeratorFactorial(5.0) << std::endl;
}

请注意,您无法在主函数中声明函数

这种事情是编程基础,似乎你在学会走路之前试图跑步。得到像C++ Primer这样的好书并自己节奏。