0

我正在尝试为此编写一个小循环

在此处输入图像描述

其中 Pi 是 k 范围内论证的(如果你不知道,只是彻底的)产品。有点像求和符号。无论如何,我似乎无法理解如何写这个。我写了这个小函数,但这不是我想要的。它只是在我指定的范围内打印 (7i - 2) 的结果。它不是将它们全部相乘,我知道我没有要求它这样做。我什至不知道如何要求它这样做。寻找提示,不一定是答案(不过,那也很好)。

到目前为止我所做的:

void prod(long int& num)
{
    for ( int i = 1; i <= 25; ++i)
    {
        num =(-1.0)*((7.0*i - 2));

        std::cout << num << std::endl;

    }
}
4

4 回答 4

3

在几个层面上,这是一个有趣的问题,但有一些问题需要指出。首先,nhgrif 发布的算法是正确的(因此被接受),但请记住,对于给定的“product”函数,“int”和“long”返回值都很快溢出,所以代码实际上从来没有给出 k = 25 的正确答案。事实上,对于 int 类型,上述算法只给出 k = 7 的正确答案,即 1838865600(在我的机器上)。之后,对于 k >= 8,数值不正确。

这可以通过运行 nhgrif 的算法来看到,其中 prod() 函数的输出显示为 up k = 10:

i = 1: -5
i = 2: -60
i = 3: -1140
i = 4: -29640
i = 5: -978120
i = 6: -39124800
i = 7: -1838865600
i = 8: -2147483648
i = 9: -2147483648
i = 10: -2147483648
.
.
.

从上面我们看到 int 的最大值(以大小为单位)在 i = 8 时很快达到,可以通过运行来检查:

#include <iostream>
#include <limits>

int main(int argc, const char * argv[]) 
{    
    int maxInt = std::numeric_limits<int>::max();
    std::cout << "max: " << maxInt << std::endl;
    return 0;
}

给出期望值:

max: 2147483647

我们还看到,对于 long 数据类型,我们有同样的问题,但可以将其增加到 k = 12,直到 long 的限制达到 k = 13,即:-9223372036854775808。

最重要的是,上面发布的代码对 Matt 最初要求的 k = 25 的值给出了错误的答案。

解决方案是对数字使用字符串表示。这种字符串表示通常用于超出普通数据类型限制的大量数字(例如,魔方的# of Rubik's cube states 或一克碳中的原子# of atom)。但我认为这可能需要一些思考,因为计算需要表示为对字符串的操作,以避免直接处理整数和长整数。

有趣的是,Matt 给出的函数直接求和为任意 k 的闭合解:

在此处输入图像描述

用 Gamma 函数表示,这需要在 C++ 中定义一些额外的代码(但 C++ 11 已经定义了它)。

作为参考,对于 k = 25,Matt 的 prod() 函数的答案是:-6472463290438308956636841782995191201792000000

对于它的价值,您还可以递归地编写算法:

#include <iostream>

long prod(int k);

int main(int argc, const char * argv[])
{
    int k = 10;
    for (int i = 1; i <= k; i++) {
        std::cout << "i = " << i << ": " << -prod(i) << std::endl;
    }

    return 0;
}

long prod(int k) {
    if (k == 1) {
    return 5;
    }
    else {
        return (7*k - 2)*prod(k - 1);
    }
}

但是这段代码也有上面讨论的同样的溢出问题。

于 2013-11-05T05:36:23.807 回答
2
num = 1;    
for (int i=1; i <= 25; ++i)
{
    num *= ((7.0*i - 2));
    std::cout << -num << std::endl;
}
num *= -1;
std::cout << num << std::endl;

细微的差别。

操作员是这样工作的*=......

A *= B;

和写这个完全一样……

A = A * B;

它将左侧的值乘以右侧的值并将其分配给左侧的值。

您可以对所有数学运算符执行相同的操作:+=-=*=/=%=


bruce3141编辑:作为一个注释,正如's answer正确指出的那样,在你到达之前,intlong longdata 类型都会导致溢出k = 25,所以就目前而言,虽然这个算法是正确的,但它不会给你正确的结果由于溢出的计算机。使用浮点数据类型例如double不是一个可接受的解决方案。您需要研究一个可以处理大于long long将存储的整数的类。我不确定C++有什么,但您正在寻找与Java'BigInteger类等效的东西。

于 2013-11-05T03:47:05.190 回答
1

初始化num为1,然后将其放入while

num = num*((7.0*i - 2));

最后乘以它-1

于 2013-11-05T03:47:11.367 回答
-1
double prod(unsigned int k)
{
    double result = 1;
    for(int i = 1; i <= k; i ++)
    {
        result * = 7*i - 2;
    }
    return -result;
}

您可以将其用作:

std::cout<<prod(25);

这个怎么运作:

for(int i = 1; i <= k; i ++)
    {
        result * = 7*i - 2;
    }

计算表达式的 pi 部分因为 -1 不在 pi 表达式中,所以我只将结果乘以 -1 一次,然后在 return 语句中返回它:

return -result;

编辑:

每个数学表达式(没有未知数)总是等于一个值。因此,最好通过使函数返回表达式的值来表示该表达式。返回一个值使函数比仅将值打印到控制台更可重用。
例如。我可以做类似的事情 double x = prod(3) + prod(4);

由于存在一个未知数(上限 k),因此我将其作为函数的参数,以便代码可以与不同的 k 上限值一起使用。

遵循良好的设计模式总是好的,以避免稍后通过重构代码来浪费时间。

于 2013-11-05T03:49:52.610 回答