gpt4 book ai didi

使用和不使用命名空间标准的 C++ 长 double 差异;

转载 作者:行者123 更新时间:2023-12-05 08:45:29 26 4
gpt4 key购买 nike

我偶然发现了我无法解释的古怪 C++ 行为。

我正在尝试在调整图像大小时(保持其比例)以适应尽可能多的屏幕时计算图像的尺寸。 x、y 变量是图像的尺寸,X、Y 变量是屏幕的尺寸。当生成的维度不是整数时,我需要使用标准数学规则对其进行舍入。

此程序的输入 499999999999999999 10 1000000000000000000 19 给出了(不正确的)答案 9500000000000000000000000000000000000000000000000000000000000019

#include <iostream>
#include <cmath>
#include <algorithm>

int main()
{
long long x, y, X, Y;
std::cin >> x >> y >> X >> Y;

long double ratio = std::min((long double)X/x, (long double)Y/y);

x = round(ratio*x);
y = round(ratio*y);

std::cout << x << " " << y << std::endl;
return 0;
}

但是,下面的代码(唯一的变化是 using namespace std; 和从 main 函数体中删除 std::)给出了正确的答案949999999999999998 19

#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;

int main()
{
long long x, y, X, Y;
cin >> x >> y >> X >> Y;

long double ratio = min((long double)X/x, (long double)Y/y);

x = round(ratio*x);
y = round(ratio*y);

cout << x << " " << y << endl;
return 0;
}

我正在使用 g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0 并使用 g++ -std=c++17 -Wall -Wextra - 编译程序Wshadow.

最佳答案

在第一种情况下,您正在调用 double round(double)来自全局命名空间的函数,它由 cmath header 引入。

在第二种情况下,您正在调用重载 long double std::round(long double)std 命名空间运行,因为您正在 using namespace std

您可以通过在 round 前面添加 std:: 来修复您的代码,如:

#include <iostream>
#include <cmath>
#include <algorithm>

int main()
{
long long x, y, X, Y;
std::cin >> x >> y >> X >> Y;

auto ratio = std::min((long double)X / x, (long double)Y / y);

x = std::round(ratio * x); // <-- add std:: here
y = std::round(ratio * y); // <-- add std:: here

std::cout << x << " " << y;
return 0;
}

更新:

为了解释这里发生了什么,当您在第一种情况下调用 round 时,ratio * x 被隐式转换为 double(这在传递给函数之前只能存储 15 位有效数字。

这会导致精度损失和您的情况出现意外结果。没有怪癖。

关于使用和不使用命名空间标准的 C++ 长 double 差异;,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72588650/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com