如何在 C++ 中安全地将双精度数转换为整数?
How do I safely convert a double into an integer in C++?
有没有一种方法可以将双精度数转换为整数,而不会在过程中冒任何意外错误的风险?我在 Programming - Principles and Practice Using C++(一本由 c++ 的创建者编写的书)中读到,double 不能转换为整数,但我已经对其进行了测试,它在大约 80% 的时间内正确转换。如果可能的话,完全没有风险地做到这一点的最佳方法是什么?
例如,这可以正确转换。
double bruh = 10.0;
int a = bruh;
cout << bruh << "\n";
但这不是。
double bruh = 10.9;
int a = bruh;
cout << bruh << "\n";
简而言之,它不会自动舍入,所以我认为这就是它“不安全”的原因。
不可能将所有双精度数转换为整数而不会有丢失数据的风险。
首先,如果双精度数包含小数部分 (42.9),则该小数部分将丢失。
其次,与大多数整数相比,双精度数可以容纳更大范围的值,约为 1.7e308,因此当您进入更大的值时,您根本无法将它们存储为整数。
way to convert a double into an integer without risking any undesired errors
in short, it doesn't round automatically so I think that's what constitutes it as "unsafe"
要转换为整数值:
x = round(x);
要转换为整数类型:
从像 long lround(double x);
这样的圆形函数开始。它“Returns 值最接近 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_MIN
和 LONG_MAXP1
,它们的大小是 2 的幂并且很容易精确地表示为 double
.
有没有一种方法可以将双精度数转换为整数,而不会在过程中冒任何意外错误的风险?我在 Programming - Principles and Practice Using C++(一本由 c++ 的创建者编写的书)中读到,double 不能转换为整数,但我已经对其进行了测试,它在大约 80% 的时间内正确转换。如果可能的话,完全没有风险地做到这一点的最佳方法是什么?
例如,这可以正确转换。
double bruh = 10.0;
int a = bruh;
cout << bruh << "\n";
但这不是。
double bruh = 10.9;
int a = bruh;
cout << bruh << "\n";
简而言之,它不会自动舍入,所以我认为这就是它“不安全”的原因。
不可能将所有双精度数转换为整数而不会有丢失数据的风险。
首先,如果双精度数包含小数部分 (42.9),则该小数部分将丢失。
其次,与大多数整数相比,双精度数可以容纳更大范围的值,约为 1.7e308,因此当您进入更大的值时,您根本无法将它们存储为整数。
way to convert a double into an integer without risking any undesired errors
in short, it doesn't round automatically so I think that's what constitutes it as "unsafe"
要转换为整数值:
x = round(x);
要转换为整数类型:
从像 long lround(double x);
这样的圆形函数开始。它“Returns 值最接近 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_MIN
和 LONG_MAXP1
,它们的大小是 2 的幂并且很容易精确地表示为 double
.