如何检查商是否为整数?C++

How to check if quotient is an integer? C++

本文关键字:是否 整数 C++ 何检查 检查      更新时间:2023-10-16

我是初学者,我正在寻找一种方法来检查C++中的商是否是整数。

例如:

int a;
double b;
cin >> a;
b = a / 4;

我怎么知道 b 不是整数(比如 5/4=1.25)?

在像 C 这样的语言中,当声明整数类型的变量时,其中的值将始终是整数。但是,我想您要问的是,如何检查计算结果是否为整数值。如果您使用整数类型进行算术运算,那么最天真的方法是执行逆运算并测试结果是否与原始输入匹配。

编辑如果两个操作数都是整数类型(如问题编辑之前),那么您可以这样做:

b = a / 4;
if( b*4 == a ){
cout << "a/4 is integer";
}

但是,还有其他方法可以做到这一点。例如,使用余数运算符%(经常与模混淆 - 或者更确切地说是误判)。在许多 CPU 架构上,执行除法的操作也会给出余数。这

b = a / 4;
if( b%4 == 0 ){
cout << "a/4 is integer";
}

将接近最佳状态,因为单个 CPU 指令将执行两个计算(在前两行上),并且如果没有余数,比较通常会测试除法操作设置的特殊标志。

*但是,如果浮点运算进入图片(如问题编辑后如何),事情会变得更加麻烦。您无法再执行反演测试,因为浮点运算不精确¹。

如果您只关心余数/模数,则最好的选择是使用fmod函数,然后测试结果是否在精确误差 epsilon 的范围内。

if( DBL_EPSILON > fmod(a, 4) ){
cout << "a/4 is integer (within double floating point precision)";
}

如果你同时需要商和余数,那么我的首选方法是截断和减去(通常更快):

double b = a/4.;
double b_r = b - trunc(b);
if( DBL_EPSILON > fabs(b_r) ){
cout << "a/4 is integer (within double floating point precision)";
}

1:对于涉及的大多数数字;有一组数字,当用于浮点算术运算时,将产生精确的结果。但这只是可由浮点表示的所有数字的一小部分。

你不需要检查b是否是整数,因为它总是整数。你宣布它int.

此外,由于a4也是整数,因此a/4是整数除法,因此即使表达式也永远不能是小数。

如果修复了所有这些问题,则查看浮点值是否表示整数的一种方法是将其原始值与故意截断为整数的值进行比较:

foobar == static_cast<int>(foobar)

但是,与任何浮点运算一样,这可能容易受到舍入误差的影响,因此您需要更具体地了解您的一般要求。

在所示的特定情况下,检查模要简单得多:5 % 4不为零,因此5/4不是完整的。

编辑前

您的ab变量属于您声明的int类型。无论您尝试通过标准输入提供给它们的值如何,它们都将保持为int型。a / 4表达式的类型和结果也是一个int,因为所有操作数都是整数除法中涉及的整数。

编辑后:

如果b被声明为类型double它将保持为double类型,但将收到整数除法的剪切结果,因为a / 4int类型。因此,如果所有操作数都是整数,则算术表达式的结果也将是整数。要使其成为double类型,请将其中一个操作数转换为double

double b = static_cast<double>(a) / 4;

double b = a / 4.;

正如其他答案所表明的那样,如果您将除法分配给浮点数,您将始终获得一个整数值,因为在C++(和大多数语言)中,整数除法会产生整数。

事实上,你甚至不需要b来成为float。您可以执行以下操作之一:

使用模运算符 <-推荐

int a;
std::cin >> a;
if (a % 4 == 0) { /* do something */ }

使用除数特定的可除性检验

int a;
std::cin >> a;
if (a & 0x11 == 0) { /* do something */ }

如果整数的最低有效 2 位为 0,则该整数可被 4 整除。但是,事实上,编译器可能会将之前的测试优化到这个测试。

乘以积分商

如果您打算使用 a/4,请尝试:

int a;
std::cin >> a;
auto b = a / 4; /* b is an int... */
if (b * 4 == a) { /* do something */ }

这对于固定除数的情况不是很有用;但如果它没有被修复,你可能会这样做:

int a;
std::cin >> a;
std::cin >> c;
auto b = a / c;
if (b * c == a) { /* do something */ }