这与信用卡问题有关。 因此,如果数字是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
?
答案 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!