【发布时间】:2015-07-31 14:12:56
【问题描述】:
在进行转换测试时,我在 C++ 中遇到了一些奇怪的行为。
上下文
在线C++参考指出std::numeric_limits<double>::max()(定义在limit.h)的返回值应该是DBL_MAX(定义在float.h)。在我的测试中,当我打印出这些值时,两者确实完全相同。但是,当我将它们从double 转换为int 时,出现了奇怪的事情。
“相同”的输入,不同的结果?
int32_t t1 = (int) std::numeric_limits<double>::max(); 将t1 设置为INT_MIN,但int32_t t2 = (int) DBL_MAX; 将t2 设置为INT_MAX。使用static_cast<int> 完成转换时也是如此。
'Same' 输入,相同情况下相同结果
但是,如果我定义一个函数
int32_t doubleToInt(double dvalue) {
return (int) value;
}
doubleToInt(std::numeric_limits<double>::max()) 和 doubleToInt(DBL_MAX) 都返回 INT_MIN。
为了帮助理解事物,我用 Java 实现了一个类似的程序。在那里,无论是否在函数中,所有类型转换都返回 INT_MAX 的值。
有人能指出为什么在 C++ 中结果在某些情况下是 INT_MIN,而在其他情况下是 INT_MAX 的原因吗?在 C++ 中将 DBL_MAX 转换为 int 时的预期行为应该是什么样的?
C++ 示例代码
#include <iostream>
#include <limits>
#include <float.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
template <typename T, typename D> D cast(T a, D b) { return (D) a;}
int main()
{
int32_t t1 = 9;
std::cout << std::numeric_limits<double>::max() << std::endl;
std::cout << DBL_MAX << std::endl;
std::cout << (int32_t) std::numeric_limits<double>::max() << std::endl;
std::cout << (int32_t) DBL_MAX << std::endl;
std::cout << cast(std::numeric_limits<double>::max(), t1) << std::endl;
std::cout << cast(DBL_MAX, t1) << std::endl;
return 0;
}
为了完整性:我使用的是 cygwin gcc 和 java 8。
【问题讨论】:
-
@NathanOliver 我尝试了您发布的网站上的代码,它给出了相同的答案,我注意到它使用的是 g++ c++14。这是否意味着这个问题在一些旧版本的编译器上是孤立的?
-
有可能。我在没有 c++11/14 支持的情况下重新编译,结果是一样的。奇怪的是,clang++ 给出的转换值与 g++ 不同:coliru.stacked-crooked.com/a/a686bcf40f6b1d59
-
@NathanOliver 我发现使用在线编译器编译c++代码时有优化选项。这是另一个支持在线编译的网站cpp.sh,在该网站的底部,您可以选择“优化级别”。如果我选择“none”,无论哪个 c++ 标准,它都会显示我描述的行为。这个网站tutorialspoint.com/compile_cpp_online.php 会给出同样的结果。
标签: c++ casting type-conversion double max