【问题标题】:How do I safely convert a double into an integer in C++? [closed]如何在 C++ 中安全地将双精度数转换为整数? [关闭]
【发布时间】:2020-11-22 06:12:24
【问题描述】:

有没有一种方法可以将双精度数转换为整数而不会在过程中出现任何不希望的错误?我在 Programming -Principles and Practice Using C++ (一本由 c++ 的创建者写的书)中读到了双精度数不能转换为整数,但我已经对其进行了测试,大约 80% 的时间它都能正确转换。如果可能的话,什么是完全没有风险的最佳方法?

例如,这可以正确转换。

double bruh = 10.0;
int a = bruh;
cout << bruh << "\n";

但这不是。

double bruh = 10.9;
int a = bruh;
cout << bruh << "\n";

简而言之,它不会自动舍入,所以我认为这就是它“不安全”的原因。

【问题讨论】:

  • 也许你应该表明你的意思。显然,如果双精度大于最大整数,它将不起作用。
  • 您的两个示例都有效。规则是小数部分被丢弃。
  • C++ 从 C 中获得了很多行为。你的“......没有冒任何不希望的错误的风险......”对我来说没有意义,因为这种行为是已知的。有一些函数可以进行从 double 到 int 的转换,让您可以更好地控制转换。您可以编写自己的例程来进行转换,如果它失败了您施加的任何约束,则提供 assertthrow 异常。
  • 我不确定您要避免的风险是什么。你能解释一下吗?
  • 不是迂腐,但您所说的“安全”、“适当”、“不受欢迎”和“风险”是什么意思?没有一种正确的方法可以将双精度数转换为整数。只有您想要的应用程序的方式。 (好吧,我很迂腐,但我们需要迂腐才能弄清楚你想要什么)

标签: c++ int double


【解决方案1】:

不可能将所有双精度数转换为整数而不会有丢失数据的风险。

首先,如果 double 包含小数部分 (42.9),则该小数部分将丢失。

其次,与大多数整数相比,双精度数可以保存更大的值范围,大约在 1.7e308 左右,因此当您获得更大的值时,您根本无法将它们存储到整数中。

【讨论】:

  • 有没有办法确保在转换时至少双舍入?假设双精度不大于整数的最大大小。
  • std::round 可能是一个起点。还有std::ceilstd::floor
  • @drescherjm 好的,谢谢。我还没有尝试过圆形功能,但我会看看它是否适合我。
  • @Anthony 我不会尝试这个功能,我会阅读一些关于它的文档,看看它是否符合您的要求。从你到目前为止所描述的想要我会说ceil 是你想要的。
  • @Anthony ceil 向上取整,round 向上取整或向下取整。
【解决方案2】:

将双精度数转换为整数而不冒任何意外错误的方法
简而言之,它不会自动舍入,所以我认为这就是它“不安全”的原因

转换为整数值:

x = round(x);

转换为整数类型:

从像long lround(double x); 这样的圆形函数开始。它“返回与 x 值最接近的整数值,中间情况从零四舍五入。”

如果舍入结果超出long 范围,则会出现问题,代码可能需要先进行测试。

// Carefully form a double the is 1 more than LONG_MAX
#define LONG_MAXP1 ((LONG_MAX/2 + 1)*2.0)

long val = 0;
if (x - LONG_MAXP1 < -0.5 && x - LONG_MIN > -0.5) {
  val = lround(x);
} else {
  Handle_error();
}

详细信息:为了测试double 是否在四舍五入到long 的范围内,仔细测试端点很重要。数学有效范围是(LONG_MIN-0.5 ... LONG_MAX + 0.5),但这些端点可能无法准确表示为double。相反,代码使用附近的 LONG_MINLONG_MAXP1,它们的大小是 2 的幂,很容易精确地表示为 double

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-23
    • 1970-01-01
    • 1970-01-01
    • 2013-04-05
    • 2016-01-01
    • 2013-05-13
    • 2014-04-18
    相关资源
    最近更新 更多