为了在 Luhn 算法中获得正确的数字,我的 C 代码中缺少什么?
What am i missing in my C code in order to achieve the right number in Luhn’s Algorithm?
我是 C 语言编程的新手,我正在尝试解决 CS50 的 pset1 问题,Luhn 的算法来检查信用卡是否有效。
我用来测试的示例是这张卡 Visa:4003600000000014.
As referred in the problem, first underline every other digit, starting with the number’s second-to-last digit:
[4] 0 [0] 3 [6] 0 [0] 0 [0] 0 [0] 0 [0] 0 [1] 4
Multiply the underlined digits by 2:
1•2 + 0•2 + 0•2 + 0•2 + 0•2 + 6•2 + 0•2 + 4•2
That gives:
2 + 0 + 0 + 0 + 0 + 12 + 0 + 8
Add those products’ digits (i.e., not the products themselves) together:
2 + 0 + 0 + 0 + 0 + 1 + 2 + 0 + 8 = 13
#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(void)
{
// Variable assignment
long card;
int case1, case2, mod, mod2;
// Get input from user
do
{
card = get_long("Card: ");
}
while (card <= 0);
// Case 1
for (long checksum = card; checksum > 0; checksum = checksum / 10)
{
mod = remainder(checksum, 10) * 2;
if (mod >= 10)
{
mod2 = remainder (mod, 10);
case1 = case1 + mod2;
mod = mod / 10;
case1 = case1 + mod;
}
else
{
case1 = case1 + mod;
}
checksum = checksum / 10;
printf("\n%d", case1);
}
}
我的输出:
~/pset1/credit/ $ ./credit
Card: 4003600000000014
8
8
8
8
8
8
14
14
打印出来的数字应该是13,不知道为什么我打印出来的数字是14。
尽管我得到 2 和 -6 的输出,但我已尝试更改代码。也试过 CS50 调试工具,但没有成功。
为了输出 13,我的代码缺少什么?
您从 最后 位而不是倒数第二位开始,因此您使用的是错误的一组数字。
您需要从数字 / 10 开始才能获取倒数第二个数字。
for (long checksum = card / 10; checksum > 0; checksum = checksum / 10)
这不是 minimal reproducible example。 get_long
不是标准的 C 函数,因此您必须包含另一个头文件才能编译此代码。请求调试帮助时,请始终提供完整示例。
case1
未初始化。将其初始化为零。
checksum
被初始化为 card
,并且循环检查从最后一位开始的每隔一个数字。所以它对你不想以这种方式添加的数字进行操作。更改循环,使 checksum
以 card/10
.
开头
remainder
是一个 double
函数。混合使用浮点运算和整数运算通常是不明智的,尤其是当您不熟悉浮点运算时。调用 remainder
会将其操作数转换为 double
,这可能会导致舍入错误,在这种情况下会产生不需要的结果。
remainder
提供对称余数;它 returns [−y/2, +y/2] 中的一个值,其中 y 是第二个操作数。您不想要负值。请改用整数余数运算符 %
。
避免对信用卡“号码”使用整数类型。信用卡“号码”更恰当地是数字串的标识符——它们的数值与其目的无关(例如,它们不是发行卡的数量),并且在某些 C 实现中, long
类型不够宽,无法表示整个“数字”。字符数组就足够了,尽管您必须将数字字符(“0”到“9”)转换为数字值(“0”到“9”),这可以通过减去字符常量 '0'
来自数字字符代码。
不要打印 "\n%d"
。将您的输出安排为将换行符放在最后,除非您即将接受输入并希望提示与输入在同一行,或者您故意不希望文本必须输出。通常,终端(物理或虚拟)的标准输出是行缓冲的,这意味着在发送换行符、缓冲区已满、请求输入或手动刷新缓冲区之前,输出不会出现在用户面前。
我是 C 语言编程的新手,我正在尝试解决 CS50 的 pset1 问题,Luhn 的算法来检查信用卡是否有效。 我用来测试的示例是这张卡 Visa:4003600000000014.
As referred in the problem, first underline every other digit, starting with the number’s second-to-last digit:
[4] 0 [0] 3 [6] 0 [0] 0 [0] 0 [0] 0 [0] 0 [1] 4
Multiply the underlined digits by 2:
1•2 + 0•2 + 0•2 + 0•2 + 0•2 + 6•2 + 0•2 + 4•2
That gives:
2 + 0 + 0 + 0 + 0 + 12 + 0 + 8
Add those products’ digits (i.e., not the products themselves) together:
2 + 0 + 0 + 0 + 0 + 1 + 2 + 0 + 8 = 13
#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(void)
{
// Variable assignment
long card;
int case1, case2, mod, mod2;
// Get input from user
do
{
card = get_long("Card: ");
}
while (card <= 0);
// Case 1
for (long checksum = card; checksum > 0; checksum = checksum / 10)
{
mod = remainder(checksum, 10) * 2;
if (mod >= 10)
{
mod2 = remainder (mod, 10);
case1 = case1 + mod2;
mod = mod / 10;
case1 = case1 + mod;
}
else
{
case1 = case1 + mod;
}
checksum = checksum / 10;
printf("\n%d", case1);
}
}
我的输出:
~/pset1/credit/ $ ./credit
Card: 4003600000000014
8
8
8
8
8
8
14
14
打印出来的数字应该是13,不知道为什么我打印出来的数字是14。 尽管我得到 2 和 -6 的输出,但我已尝试更改代码。也试过 CS50 调试工具,但没有成功。 为了输出 13,我的代码缺少什么?
您从 最后 位而不是倒数第二位开始,因此您使用的是错误的一组数字。
您需要从数字 / 10 开始才能获取倒数第二个数字。
for (long checksum = card / 10; checksum > 0; checksum = checksum / 10)
这不是 minimal reproducible example。
get_long
不是标准的 C 函数,因此您必须包含另一个头文件才能编译此代码。请求调试帮助时,请始终提供完整示例。case1
未初始化。将其初始化为零。
开头checksum
被初始化为card
,并且循环检查从最后一位开始的每隔一个数字。所以它对你不想以这种方式添加的数字进行操作。更改循环,使checksum
以card/10
.remainder
是一个double
函数。混合使用浮点运算和整数运算通常是不明智的,尤其是当您不熟悉浮点运算时。调用remainder
会将其操作数转换为double
,这可能会导致舍入错误,在这种情况下会产生不需要的结果。remainder
提供对称余数;它 returns [−y/2, +y/2] 中的一个值,其中 y 是第二个操作数。您不想要负值。请改用整数余数运算符%
。避免对信用卡“号码”使用整数类型。信用卡“号码”更恰当地是数字串的标识符——它们的数值与其目的无关(例如,它们不是发行卡的数量),并且在某些 C 实现中,
long
类型不够宽,无法表示整个“数字”。字符数组就足够了,尽管您必须将数字字符(“0”到“9”)转换为数字值(“0”到“9”),这可以通过减去字符常量'0'
来自数字字符代码。
不要打印 "\n%d"
。将您的输出安排为将换行符放在最后,除非您即将接受输入并希望提示与输入在同一行,或者您故意不希望文本必须输出。通常,终端(物理或虚拟)的标准输出是行缓冲的,这意味着在发送换行符、缓冲区已满、请求输入或手动刷新缓冲区之前,输出不会出现在用户面前。