为什么(int)55 == 54在C ++中?

问题描述 投票:19回答:8

所以我正在学习C ++。我已经用完了“ C ++编程语言”和“有效的C ++”,并且正在运行Euler项目。问题1 ...邓佐问题2 ...不是很多。我正在使用Win32控制台应用程序在VS2008中工作。

400万以下的斐波那契数列的所有偶数项之和是多少?

这没有用,所以我减少到100个测试用例...

这是我写的...

// Problem2.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    cout << "Project Euler Problem 2:\n\n";
    cout << "Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:\n\n";
    cout << "1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...\n\n";
    cout << "Find the sum of all the even-valued terms in the sequence which do not exceed four million.\n\n";
    cout << "Answer:  " << Solve();
}

double Solve() {
    int FibIndex = 0;
    double result = 0.0;
    double currentFib = GenerateNthFibonacciNumber(FibIndex);
    while (currentFib < 100.0){
        cout << currentFib << " " << (int)currentFib << " " << (int)currentFib % 2 << "\n";
        if ((int)currentFib % 2 == 0){
            result += currentFib;
            cout<<(int)currentFib;
        }
        currentFib = GenerateNthFibonacciNumber(++FibIndex);
    }
    return result;
}

double GenerateNthFibonacciNumber(const int n){
    //This generates the nth Fibonacci Number using Binet's Formula
    const double PHI = (1.0 + sqrt(5.0)) / 2.0;
    return ((pow(PHI,n)-pow(-1.0/PHI,n)) / sqrt(5.0));
}

这是输出...

欧拉计划问题2:

斐波那契语中的每个新术语序列是通过添加前两个学期。从1开始和2,前10个词为:

1、2、3、5、8、13、21、34、55、89,...

求所有偶数值的和序列中没有的术语超过四百万。

0 0 0 1 1 1 1 1 1 2 2 20 3 3 1 5 5 1 8 8 0 1313 1 21 21 1 34 34 0 55 540 89 89 1答案:99

所以我有三列调试代码... generate函数返回的数字(int)generateNumber和(int)generatedNumber%2

所以我们在第11个任期

55,54,0

为什么(int)55 = 54?

c++ fibonacci
8个回答
56
投票

投射到int会截断数字-就像您叫floor(currentFib)一样。因此,即使currentFib54.999999 ...(一个非常接近55的数字,在打印时也会四舍五入),(int)currentFib也会产生54。


13
投票

由于浮点舍入,该55行正在计算类似54.99999的值。将double转换为int会立即截断.99999。

在我的机器上,打印显示(currentFib-(int)currentFib)的列显示的错误为1.42109e-14。因此更像是0.999999999999986。


4
投票

好吧,简短的答案是,在任何情况下(int)55 == 54,因此您需要开始问自己相关代码行的实际作用。

第一个问题:==与类型转换相比有多牢固?


4
投票

Shog9正确,将double类型用于这样的问题,如果要将内容强制转换为int,则不是最佳方法。如果您的编译器支持,则应使用long long或其他64位整数类型,几乎可以肯定的是,所有偶数项的总和小于Fibonacci序列的400万。

[如果我们使用斐波那契数列遵循奇数奇数甚至奇数奇数的模式这一事实,那么如下操作就可以解决问题。

...
unsigned int fib[3];
fib[0]=1;
fib[1]=1;
fib[2]=2;

unsigned long long sum=0;

while(fib[2]<4000000)
{
    sum+=fib[2];

    fib[0]=(fib[1]+fib[2]);
    fib[1]=(fib[2]+fib[0]);
    fib[2]=(fib[0]+fib[1]);
}

std::cout<<"The sum is: "<<sum<<". \n";
....

应该可以解决问题的方法,也许有更快的方法,但是这种方法非常直接且易于阅读。

看着它,我意识到您可能可以使用标准的无符号32位整数作为总和,但是为了以防万一,我将其保留。

另外,您的代码对第n个斐波纳契数生成函数进行了大量的函数调用。一个不错的优化编译器将内联这些调用,但是如果不这样做,则由于函数调用比其他技术更昂贵,因此事情将会变慢。


2
投票

我同意shog9的回答100%-使用您用于计算斐波那契的算法,您必须非常小心浮点值。我发现页面cubbi.com: fibonacci numbers in c++似乎显示了获取它们的其他方法。


2
投票

我知道这不会帮助您解决真正的问题,但是您提到您正在学习C ++。为了学习的目的,我建议尽可能地靠近ANSI。我认为这是MSVC上的/Za(您可能正在使用),或GCC上的-ansi -pedantic


2
投票

以上所有建议不要将浮点值用于整数数学的注解!


0
投票

中断生成代码,有时浮点数不符合我们在长表达式中使用时的思维方式...破坏代码并对其进行检查。

© www.soinside.com 2019 - 2024. All rights reserved.