Why does same code in C++ and Python generate different outputs?

时间:2019-04-08 12:59:29

标签: c++ python-3.x

I have the TaxiCab number program implemented in both Python and C++, I dont understand why same code gives different out put, can someone enlighten me on the workings of these loops.

Check the output of the codes, both language skipped certain pairs of answers.

#include <iostream>
#include <cmath>
#include <ctime>
#include "iomanip"

using namespace std;

int ramanujan(int n) {
  int count = 0;
  int i = 0;
  int x;
  int y;
  std::cout << "Inside Ramanujan Function and out\n";
  std::cout << setw(10) << "a" << setw(10) << "b" << setw(10) << "c" << setw(10)
            << "d" << setw(20) << "TaxiCab" << '\n';
  std::cout << "\n"; // Needless to say you can ignore cout<<
  for (i = 1; i < n; i++) {
    for (int j = i + 1; j < n; j++) {
      for (int a = i + 2; a < n; a++) {
        for (int b = a; b < n; b++) {
          x = std::pow(i, 3) + std::pow(j, 3);
          y = std::pow(a, 3) + std::pow(b, 3);
          if (x == y && i != j && i != b && i != a && j != a && j != b &&
              a != b) {
            std::cout << setw(10) << i << setw(10) << j << setw(10) << a
                      << setw(10) << b << setw(20) << x << '\n';
            count = count + 1;
            if (count > 15) {
              return 0;
            }
          }
        }
      }
    }
  }
  return 1;
}

int main() {
  clock_t begin = clock();
  ramanujan(50);
  std::cout << "Done!\n";
  clock_t end = clock();
  double timeSec = (end - begin) / static_cast<double>(CLOCKS_PER_SEC);
  std::cout << timeSec << " Seconds taken";
}

Python version

import time
from numba import njit


@njit  # Comment this line if there is a Numba error
def ramanujan(n):
    count = 0
    print("a   b    c    d    TaxiCab")
    for x in range(1, n):
        for y in range(x, n):
            for a in range(x, n):
                for b in range(a, n):  # Python for loops

                    z = (x ** 3) + (y ** 3)
                    z2 = (a ** 3) + (b ** 3)

                    if (
                        z == z2
                        and x != y
                        and x != a
                        and x != b
                        and y != a
                        and y != b
                        and a != b
                    ):
                        print(x, y, a, b, z)
                        count = count + 1
                        if count > 15:
                            return  # Breaks all for loops once 10 such pairs are found


# Dont worry about the problem setup

start = time.time()
ramanujan(50)
print("Done")
end = time.time()
print(end - start)

2 个答案:

答案 0 :(得分:0)

由于浮点数的精度有限,使用std::pow评估整数的幂容易产生舍入误差。

如果需要精确的值并且没有整数值范围溢出的风险,则更好的方法(可能更快)是使用简单的乘法。

如果我正确理解,以下是用于解决OP问题的稍微改进的(IMHO)算法。

#include <iostream>
#include <iomanip>
#include <vector>
#include <utility>
#include <map>

int ramanujan(int n)
{    
    using std::setw;
    // Evaluate all the possible pairs and collect the sums
    std::map<long, std::vector<std::pair<int, int>>> sums;
    for (int i = 1; i <= n; i++) {
        for (int j = i + 1; j <= n; j++) {
            auto sum =  long(i) * i * i + long(j) * j * j;
            auto it = sums.find(sum);
            if ( it != sums.end() )
                it->second.emplace_back(i, j);
            else
                sums.emplace(sum, std::vector<std::pair<int, int>>{{i, j}});
        }
    }

    // Now print only the sums of powers (sorted) that
    // are generated by more then one couple
    int count = 0;
    std::cout << setw(8) << "a" << setw(8) << "b"
              << setw(8) << "c" << setw(8) << "d" << setw(16) << "TaxiCab" << '\n'
              << "------------------------------------------------------\n";
    for (auto const & i : sums)
    {
        if ( i.second.size() > 1 )
        {
            ++count;
            std::cout << setw(8) << i.second[0].first     // a
                      << setw(8) << i.second[0].second    // b
                      << setw(8) << i.second[1].first     // c
                      << setw(8) << i.second[1].second    // d
                      << setw(16) << i.first << '\n';     // a^3 + b^3 (= c^3 + d^3)
        }
    }
    return count;
}

如果超过50,则将输出

       a       b       c       d         TaxiCab
------------------------------------------------------
       1      12       9      10            1729
       2      16       9      15            4104
       2      24      18      20           13832
      10      27      19      24           20683
       4      32      18      30           32832
       2      34      15      33           39312
       9      34      16      33           40033
       3      36      27      30           46683
      17      39      26      36           64232
      12      40      31      33           65728
       4      48      36      40          110656
       6      48      27      45          110808
Done!

答案 1 :(得分:0)

问题是由于std :: pow(x,n)函数引入的舍入错误。它返回一个浮点数并导致舍入错误。用long(i) i i代替pow(i,3)解决了这个问题。

任何人都可以评论为什么舍入错误对于Python来说不​​是问题吗?