[英]Credit program doesn't compile
我試圖制作一個 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);
~^~~~~~~~~~~~
您不能對雙精度(或浮點數)執行模數運算。 原因很簡單,余數只為整數算術定義。 如果我將 2.3 除以 0.4,余數是多少??
因此,要執行您想要的操作,您需要將 double ( a 和 pow 的結果) 投射到盡可能長的時間。
所以你可以做((long long) a) % (long long) pow( ... )
並且應該沒問題。
將來您應該查看錯誤消息(以及警告)。
在這里它清楚地說明了二進制表達式的無效操作數並標記了 % 運算符。
pow
返回一個 double 並且%
運算符僅針對整數定義。 我認為這應該可以解決您的問題。
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;
}
您如何期望在兩個雙精度值之間進行模運算( %
)?
10.3 % 5.2
究竟是什么?
錯誤信息只是說, “你不能做雙模雙”
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.