信用计划无法编译

时间:2017-03-28 03:52:37

标签: c cs50

我试图制作一个C程序来检查银行卡是否有效。

根据Luhn的算法,您可以确定信用卡号是否(语法上)有效,如下所示:

将所有其他数字乘以2,从数字的倒数第二位开始,然后添加这些数字'数字在一起。

将总和添加到未乘以2的数字之和。

如果总的最后一位数为0(或者更正式地说,如果总模数10与0一致),则该数字有效!

这有点令人困惑,所以让我们试试我的AmEx示例:378282246310005。

为了便于讨论,让我们首先在每个其他数字下划线,从数字的倒数第二位开始:

378282246310005

好的,让我们将每个带下划线的数字乘以2:

7•2 + 2•2 + 2•2 + 4•2 + 3•2 + 0•2 + 0•2

这给了我们:

14 + 4 + 4 + 8 + 6 + 0 + 0

现在让我们添加这些产品'数字(即不是产品本身)在一起:

1 + 4 + 4 + 4 + 8 + 6 + 0 + 0 = 27

现在让我们将总和(27)加到未乘以2的数字之和:

27 + 3 + 8 + 8 + 2 + 6 + 1 + 0 + 5 = 60

是的,这笔金额中的最后一位数字(60)是0,所以我的名片是合法的!

因此,验证信用卡号码并不难,但手动确实有点单调乏味

#include <cs50.h>
#include <math.h>
#include <stdio.h>

int length(long long n);
int num_at(int x,long long y);
long long flip(double a);

int main(void)
{
    //int total2=0;
    //printf("Number: ");
    //int i=get_int();
    long long ll=get_long_long();
    //if (ll<=0)
    //{
    //    printf("INVALID\n");
    //}
    //for (int i=1;2*i<length(ll);i++)
    //{
    //    total2=total2+2*num_at(i,ll);
    //}
    //int total1=0;
//for (int i=0;2*i<length(ll);i++)
//{
//    total1=total1+num_at(i,ll);
//}
//int total=total1+total2;
//printf("%i\n",total);
printf("%lli\n",flip(ll));
}

int length(long long n)/* length of number */
{
    long long x=1;
    int len=0;
    while(n-n%x!=0)/* x % y means x mod y*/
    {
        len++;
        x=x*10;
    }
        return len;
}
int num_at(int x,long long y)/* digit at specific spot in number */
{
    int digit=0;//the digit at position z(see below)
    int z=1;
    for(z=x;z>=0;z--)
    {
        digit=y%10;
        y=y-y%10;
        y=y/10;
    }
    return digit;
}
long long flip(double a)//flips a
{
    long long b=0;
    for(int y=0;y<length(a);y++)
    {
        b=b*10;
        b=b+(a%pow(10.0,y+1)-a%pow(10.0,y))/pow(10.0,y);
    }
    return b;
}

编译时的错误是:

credit.c:99:15: error: invalid operands to binary expression ('double' and 'double')
    b=b+(a%pow(10.0,y+1)-a%pow(10.0,y))/pow(10.0,y);
         ~^~~~~~~~~~~~~~
credit.c:99:31: error: invalid operands to binary expression ('double' and 'double')
    b=b+(a%pow(10.0,y+1)-a%pow(10.0,y))/pow(10.0,y);
                         ~^~~~~~~~~~~~

4 个答案:

答案 0 :(得分:1)

您不能对double(或float)执行模数运算。 这是因为余数仅为整数运算定义。如果我将2.3除以0.4,剩下的是什么?

所以要做你想做的事,你需要长时间施放双倍(a和pow的结果)。

所以你可以做((long long) a) % (long long) pow( ... )而且应该没问题。

将来您应该查看错误消息(以及警告)。

这里清楚地表明二进制表达式和%运算符的无效操作数被标记。

答案 1 :(得分:1)

pow返回一个double,%运算符仅定义为整数。我认为这应该可以解决你的问题。

答案 2 :(得分:1)

Algo应该更简单,你写它。 我不是C程序员,但是:

// transform LL to char []
int len = length(ll);
char card[len];
sprintf(card, "%lld", ll);
int sum =0;
for(i=0;i < len; i++)
{
    int num = card[i] - '0';
    if(i % 2 == 0)
    { sum += num; }
    else
    { 
        int tmp = num * 2; 
        sum += (tmp / 10);
        sum += (tmp % 10);
    }
}

if(sum % 10)
{ 
     // card valid 
}

在我看来更具可读性。 (对不起,如果拼写错误,这篇文章是用旧智能手机写的......)

修改 我知道你喜欢使用循环,但你的num_at也可以增强:

int num_at(int pos, long long x)
{
     return (x / (int)pow(10, pos)) % 10;
}

答案 3 :(得分:0)

您希望如何在两个double值之间进行模运算(%)?

究竟是什么10.3 % 5.2

错误信息只是说,&#34;你不能做双模双重&#34;