Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将大小转换为双倍或整数C++;_C++_Casting_Double_Size T - Fatal编程技术网

C++ 如何将大小转换为双倍或整数C++;

C++ 如何将大小转换为双倍或整数C++;,c++,casting,double,size-t,C++,Casting,Double,Size T,我的问题是 我有一个size\u t数据,但现在我想将其转换为double或int 如果我做了类似的事情 size_t data = 99999999; int convertdata = data; 编译器将报告警告。因为它可能会溢出 您是否有类似于boost或其他方法的转换方法?静态转换: static_cast<int>(data); static_cast(数据); 演员阵容: size\u t data=9999999; int convertdata=静态转换(数

我的问题是

我有一个size\u t数据,但现在我想将其转换为double或int

如果我做了类似的事情

 size_t data = 99999999;
 int convertdata = data;
编译器将报告警告。因为它可能会溢出

您是否有类似于boost或其他方法的转换方法?

静态转换:

static_cast<int>(data);
static_cast(数据);
演员阵容:

size\u t data=9999999;
int convertdata=静态转换(数据);
很可能会使警告静音(尽管原则上编译器可以对它喜欢的任何东西发出警告,即使有强制转换)

但这并不能解决警告告诉您的问题,即从
size\u t
int
的转换确实可能溢出

如果可能,请设计您的程序,这样您就不需要将
size\u t
值转换为
int
。只需将其存储在
size\t
变量中(正如您已经做的)并使用它即可

转换为
double
不会导致溢出,但会导致非常大的
size\t
值的精度损失。同样,将
size\u t
转换为
double
也没有多大意义;最好还是将值保留在
size\t
变量中


(如果无法避免强制转换,则有一些建议,例如在溢出时引发异常。)

如果您的代码准备处理溢出错误,则可以在
数据过大时引发异常

size_t data = 99999999;
if ( data > INT_MAX )
{
   throw std::overflow_error("data is larger than INT_MAX");
}
int convertData = static_cast<int>(data);
size\u t data=9999999;
如果(数据>整数最大值)
{
throw std::overflow_error(“数据大于INT_MAX”);
}
int convertData=静态转换(数据);
您可以使用Boost

如果源值超出目标类型的范围,但在转换为
double
时未检测到精度损失,则会引发异常


但是,无论您使用什么函数,您都应该决定在
size\u t
中的值大于
INT\u MAX
的情况下希望发生什么。如果您想检测它,请使用
numeric\u cast
或编写自己的代码进行检查。如果您不知何故知道这不可能发生,那么您可以使用
static\u cast
来抑制警告,而无需花费运行时检查,但在大多数情况下,成本并不重要。

假设无法重新设计程序以避免强制转换(参考文献):

要从size\u t转换为int,您需要确保size\u t不超过int的最大值。这可以通过以下方法完成:

int大小点(大小数据)
{
如果(数据>标准::数值限制::最大值())
抛出std::异常(“无效转换”);
返回标准::静态_转换(数据);
}

如果你需要从siZeIt中转换为一倍,并且你需要确保你不会丢失精度,我认为你可以使用一个窄的转换(参考文献StruouStru: C++编程语言,第四版):

模板
目标窄播(源v)
{
自动r=静态(v);
如果(静态施法(r)!=v)
抛出运行时错误(“窄强制转换失败”);
返回r;
}
我通过检查最大整数浮点可表示整数的限制(代码使用googletest),使用大小转换到双精度转换的窄转换进行测试:

EXPECT_EQ(静态_cast(窄播(size_t{IntegerRepresentableBoundary()-2})),size_t{IntegerRepresentableBoundary()-2});
EXPECT_EQ(静态_cast(窄播(size_t{IntegerRepresentableBoundary()-1})),size_t{IntegerRepresentableBoundary()-1});
EXPECT_EQ(静态_cast(窄播(size_t{IntegerRepresentableBoundary()})),size_t{IntegerRepresentableBoundary()});
EXPECT_THROW(窄播(size_t{IntegerRepresentableBoundary()+1}),std::exception);
EXPECT_EQ(静态_cast(窄播(size_t{IntegerRepresentableBoundary()+2})),size_t{IntegerRepresentableBoundary()+2});
EXPECT_THROW(窄播(size_t{IntegerRepresentableBoundary()+3}),std::exception);
除EQ(静态转换(窄转换(大小转换{IntegerRepresentableBoundary()+4})),大小转换{IntegerRepresentableBoundary()+4});
EXPECT_THROW(窄播(size_t{IntegerRepresentableBoundary()+5}),std::exception);
在哪里

constexpr size\u t IntegerRepresentableBoundary()
{
静态_断言(std::numeric_limits::radix==2,“方法仅对二进制浮点格式有效”);

返回大小{2}是否有可能导致溢出,因为size\u t的范围比int的范围大。@user2701639那么,您希望在这种情况下发生什么?@user2701639是否有可能导致溢出…而不是使用
double
。如前所述,如果
数据
大于适合的值,则会导致溢出
int
——因此,可能会引起“兴趣”问题,如代码中的负值,CurrtDATA < /Cord>,当你认为一个大小是负的,你知道有些东西是非常错误的。而且,<代码>数据< /代码>的选择值可能导致<代码>转换数据> /代码>中的值为零,其他值可以表示大小为非常小的正数,尽管原始SIZ。e是巨大的。如果你不能避免这样的强制转换,但希望程序让你知道是否发生了超出范围的情况,这正是你所需要的。有用的回答。我提交了一个编辑,将此内容添加到接受答案的结尾,以便未来的读者在一个地方看到完整的响应。我最近遇到了一个问题,返回双精度的函数用于r当它失败时返回NPO,但是当我检查(=)函数与NPO的结果时,它没有在应该返回true时返回true。在控制台上检查时,我发现双铸造NPO比非铸造NPO(size_t)@Coyoteazul:这是一个设计糟糕的函数。更糟糕的是,它可能“工作”在32位系统上。是的。我实际上认为double的容量比size\u t大,所以我不认为
size_t data = 99999999;
if ( data > INT_MAX )
{
   throw std::overflow_error("data is larger than INT_MAX");
}
int convertData = static_cast<int>(data);
int SizeTToInt(size_t data)
{
    if (data > std::numeric_limits<int>::max())
        throw std::exception("Invalid cast.");
    return std::static_cast<int>(data);
}
template<class Target, class Source>
Target NarrowCast(Source v)
{
    auto r = static_cast<Target>(v);
    if (static_cast<Source>(r) != v)
        throw RuntimeError("Narrow cast failed.");
    return r;
}
EXPECT_EQ(static_cast<size_t>(NarrowCast<double>(size_t{ IntegerRepresentableBoundary() - 2 })), size_t{ IntegerRepresentableBoundary() - 2 });
EXPECT_EQ(static_cast<size_t>(NarrowCast<double>(size_t{ IntegerRepresentableBoundary() - 1 })), size_t{ IntegerRepresentableBoundary() - 1 });
EXPECT_EQ(static_cast<size_t>(NarrowCast<double>(size_t{ IntegerRepresentableBoundary() })), size_t{ IntegerRepresentableBoundary() });
EXPECT_THROW(NarrowCast<double>(size_t{ IntegerRepresentableBoundary() + 1 }), std::exception);
EXPECT_EQ(static_cast<size_t>(NarrowCast<double>(size_t{ IntegerRepresentableBoundary() + 2 })), size_t{ IntegerRepresentableBoundary() + 2 });
EXPECT_THROW(NarrowCast<double>(size_t{ IntegerRepresentableBoundary() + 3 }), std::exception);
EXPECT_EQ(static_cast<size_t>(NarrowCast<double>(size_t{ IntegerRepresentableBoundary() + 4 })), size_t{ IntegerRepresentableBoundary() + 4 });
EXPECT_THROW(NarrowCast<double>(size_t{ IntegerRepresentableBoundary() + 5 }), std::exception);
constexpr size_t IntegerRepresentableBoundary()
{
    static_assert(std::numeric_limits<double>::radix == 2, "Method only valid for binary floating point format.");
    return size_t{2} << (std::numeric_limits<double>::digits - 1);
}