为什么我不能只使用51 <= j <= 55? /数据类型

时间:2019-01-13 12:22:18

标签: c

这与信用卡问题有关。 因此,如果数字是16位,而前两位是51、52、53、54或55, 该卡是万事达卡。

起初,我尝试了(51 <= j <= 55)。我认为这种情况是有道理的。原因j是一个整数。但是由于某种原因,错误提示(51 <= j <= 55)始终为真(我不明白!)。 所以我不得不写(j==51 || j==52 || j==53 || j==54 || j==55),基本上与(51 <= j <= 55)相同。

int j = c / pow(10,14);

if(pow(10,15) <= c < pow(10,16) && (j==51 || j==52 || j==53 || j==54 || j==55)) 
{
    printf("MASTERCARD\n");
}

上面的代码很好用..(我不知道为什么) 我必须对j进行一些更改,从double j更改为int j。 我猜是因为51到55是整数。

无论如何,该错误并未说明pow(10,15) <= c < pow(10,16)。 为什么我不能只使用51 <= j <= 55

2 个答案:

答案 0 :(得分:7)

  

为什么我不能只使用51 <= j <= 55

因为这是解析的“特殊情况”,在您看来很明显,因为您已经习惯了,但是在C表达式语法中却根本不明显。

如果应用C的解析和优先级规则,您将得到一个表达式,它可能不是您想要的:

51 <= j <= 55

解析为

(51 <= j) <= 55

51 <= j是一个布尔表达式,其结果为1(如果51实际上小于或等于j)或否则为0。 0和1都小于55,因此表达式结果始终为1(真)。

要使其按照自己的意愿工作,必须将其明确转换为

(51 <= j) && (j <= 55)

相反,其他语言(例如Python)能够使这种表达更“人性化”,引入了chained comparisons的概念,该概念指定了如何将多链比较的序列转换为单链比较的序列比较将AND和在一起,但这是“经典”表达式评估器(以及can lead to surprises的工作方式之外的一个技巧。


偶然地,您似乎正在尝试使用浮点数来存储/处理信用卡号的16位数字。这是一个糟糕的主意,因为double有53位尾数,略小于16位十进制精度。这意味着,对于“较大的一方”的信用卡号,最后一位可能无法正确存储。更准确地说,超过9007 1992 5474 0992以外的最后一个奇数的每个信用卡号都将被整齐并四舍五入为偶数。

因此,只需使用整数数组,就可以避免令人讨厌的惊喜。

通常,如果您对数字的确切值感兴趣,请避免使用double和浮点数,除非您确切知道自己在做什么。

答案 1 :(得分:1)

使用(51 <= j) && (j <= 55)

<=运算符产生布尔结果(即1或0)。如果要检查j是否在范围内,则需要在两端产生一个布尔值,然后“和”结果。

当您链接比较运算符(例如'<=')时,它们会从左到右进行求值。对于您尝试过的操作,j的结果并不重要,因为第一个<=运算符为1或0(始终小于55)。因此最终结果始终为true。

某些语言可能对链接比较运算符有不同的规则,这与它们在数学上的使用方式更为一致,但绝对不是C!