【问题标题】:What's wrong with long? Why is subtracting 1 automatically?长有什么问题?为什么会自动减1?
【发布时间】:2018-08-16 05:12:52
【问题描述】:
#include <iostream>
#include <math.h>
#include <algorithm>

using namespace std;

int main() {
    int t, c1, c2, res;
    string str1, str2;

    cin >> t;

    for (int i = 0; i < t; i++) {
        c1 = c2 = res = 0;
        cin >> str1 >> str2;
        c1 = count(str1.begin(), str1.end(), '1');
        c2 = count(str2.begin(), str2.end(), '1');
        cout << (long)(((pow(10, c1) - 1) / 9) * ((pow(10, c2) - 1) / 9)) << '\n';
    }
}

输入:

1
11111 11111

输出是:

123454321

但是,问题来了,

输入:

1
10101 10100

输出是:

1220

还有,对于

1
11000 11000

输出:

120

如果答案的长度小于 4,我不明白为什么 long 会从最终答案中减去 1?

注意:这里,输入字符串的长度

【问题讨论】:

  • pow 适用于浮点数。 (long) 通过截断浮点数将它们转换为 long
  • 您的意思是在使用它们之前将每个指数项转换为 long,例如在一个部门?
  • @Scheff:这不是浮点精度问题。 OP 询问的计算完全可以用浮点计算,没有错误。问题是他们的pow 实现返回不准确的结果,而准确的结果是可表示的并且由良好的pow 实现返回。如果strcmp 失败是因为一个糟糕的实现错误地处理了整数,你不会说这是一个整数算术问题;你会说这是一个strcmp 错误。所以如果一个糟糕的pow 实现导致了问题,那是pow 错误,而不是浮点问题。
  • @AlanBirtles:这不是那个的复制品。

标签: c++ casting floating-point


【解决方案1】:

一些pow 实现返回不准确的结果,即使准确的结果是可表示的。微软的pow 实现因此而臭名昭著。

(long)(((pow(10, c1) - 1) / 9) * ((pow(10, c2) - 1) / 9)) 中,pow 返回的值略小于正确值,例如返回 99999.999999999985448084771633148193359375 而不是 100000。这会导致其余算术产生的值略小于 1221 而不是 1221。当即转换为long,分数被截断,产生1220

理想情况下,有足够多的人会就此向 Microsoft 或其他不良 pow 例程的发布者投诉,以便他们修复它。

鉴于存在问题,您可以通过将pow 结果四舍五入到最接近的整数(与round 函数一样)或编写您自己的电源例程来满足您的目的来解决它。

【讨论】:

  • 针对pow(10, int &lt;= 15) 的所有组合测试了Microsoft 实现,它非常准确。所以问题中描述的问题不能来自pow()
  • @MichaelVeksler:你测试了哪个版本? OP使用的是哪个版本?微软可能终于修复了它。
  • 是的,你似乎是对的。 MS 的pow() 中一定有一个错误,他们已经修复了,因为代码在 VS 2015(发布和调试)中完美运行。所以他们必须在pow() 中修复了他们的错误
猜你喜欢
  • 1970-01-01
  • 2021-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-15
  • 2018-09-22
  • 1970-01-01
相关资源
最近更新 更多