【问题标题】:Why can't I just use 51 <= j <= 55? / data types [duplicate]为什么我不能只使用 51 <= j <= 55? /数据类型[重复]
【发布时间】:2019-01-13 12:22:18
【问题描述】:

这是关于信用卡问题。 所以,如果数字是 16 位,前两位是 51、52、53、54 或 55, 该卡是万事达卡。

一开始,我试过(51 &lt;= j &lt;= 55)。我认为这个条件是有道理的。因为j 是一个整数。但是由于某种原因,错误说(51 &lt;= j &lt;= 55)总是正确的(我不明白这个!)。 所以只好写(j==51 || j==52 || j==53 || j==54 || j==55),和(51 &lt;= j &lt;= 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 jint j。 我猜是因为数字 51 到 55 是整数..?

无论如何,错误并没有说明pow(10,15) &lt;= c &lt; pow(10,16)。 为什么我不能只使用51 &lt;= j &lt;= 55

【问题讨论】:

标签: c


【解决方案1】:

为什么我不能只使用 51

因为这是解析中的一个“特殊情况”,因为你已经习惯了,所以你的脑海中很明显,但在 C 表达式语法中却一点也不明显。

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

51 <= j <= 55

被解析为

(51 <= j) <= 55

51 &lt;= j 是一个布尔表达式,其计算结果为 1(如果 51 确实小于或等于 j),否则为 0。 0 和 1 都小于 55,所以表达式结果总是 1(真)。

要让它做你想做的事,你必须明确地将其转换为

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

其他语言(例如 Python)能够对这种表达式产生更“人性化”的感觉,引入了 chained comparisons 的概念,该概念指定如何将一系列多链比较转换为一系列单比较与运算在一起,但这是一个“经典”表达式评估器如何工作之外的技巧(以及canleadtosurprises)。


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

所以,只需使用整数数组,就可以避免令人讨厌的意外。

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

【讨论】:

  • 这正是我想说的。因为它的比较:(1||0)&lt;=55
【解决方案2】:

使用(51 &lt;= j) &amp;&amp; (j &lt;= 55)

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

当您链接比较运算符(如“j 是什么并不重要,因为第一个 &lt;= 运算符的结果是 1 或 0,始终小于 55。因此最终结果始终为真。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-29
    • 1970-01-01
    • 2014-01-15
    • 1970-01-01
    • 1970-01-01
    • 2017-01-25
    相关资源
    最近更新 更多