2014-09-13 4 views
0

Я написал реализацию Алгоритм Луна. Когда я тестирую программу с номерами, которые недействительны по количеству цифр, я не получаю никакой программной ошибки. Вместо этого программа выполняет вызов printf() в основной функции. Однако всякий раз, когда я тестирую программу, используя действительные номера карт в соответствии с алгоритмом, я получаю деление на 0 ошибок. Отладка с помощью DBG дает мне арифметическую ошибку при MSVC дает мне исключение с плавающей запятой, что сужать до деления на 0. Это код:Как есть арифметическая ошибка деления на ноль в этой функции?

#include <stdio.h> 
#include <math.h> 
#include "cs50.h" // For MSVC, I used scanf_s() from stdio.h instead since cs50.h is not supported 

long long Prompt(void); // Returns credit card number 
int Validate(long long); // Returns checksum 
void Report(long long); // Prints success 

int main() 
{ 
    long long CardNumber = Prompt(); 
    int CheckSum = Validate(CardNumber); 
    if (!(CheckSum % 10)) { 
     Report(CardNumber); 
    } else { 
     printf("INVALID\n"); 
    } 
    return 0; 
} 

long long Prompt(void) 
{ 
    printf("CARD NUMBER: "); 
    long long CardNumber; 
    CardNumber = GetLongLong(); 
    return CardNumber; 
} 

int Validate(long long CardNumber) 
{ 
    int CheckSum = 0; 
    int Digit = 0; 
    int DigitCount = (int)(floor(log10l(CardNumber) + 1)); 
    for (int i = 2; i < DigitCount; i += 2) { 
     Digit = 2 * ((CardNumber % (10^i))/(10^(i - 1))); // BUG 
     if (Digit > 9) { 
      int BiDigit = Digit; 
      Digit = 0; 
      int SubDigit = 0; 
      for (int j = 0; j < 2; i++) { 
       SubDigit = (BiDigit % (10^j))/(10^(j - 1)); // BUG 
       Digit += SubDigit; 
      } 
     } 
     CheckSum += Digit; 
    } 
    for (int i = 1; i < DigitCount; i += 2) { 
     Digit = (CardNumber % (10^i))/(10^(i - 1)); 
     CheckSum += Digit; 
    } 
    return CheckSum; 
} 

void Report(long long CardNumber) 
{ 
    int DigitCount = (int)(floor(log10l(CardNumber) + 1)); 
    int Digit1 = (CardNumber % (10^(DigitCount - 1)))/(10^(DigitCount - 2)); // BUG 
    int Digit2 = (CardNumber % (10^(DigitCount - 2)))/(10^(DigitCount - 3)); // BUG 
    if (Digit1 == 4 && (DigitCount == 13 || DigitCount == 16)) 
     printf("VISA\n"); 
    else if (Digit1 == 3 && (Digit2 == 4 || Digit2 == 7) && DigitCount == 15) 
     printf("AMERICAN EXPRESS\n"); 
    else if (Digit1 == 4 && (Digit2 >= 1 || Digit2 <= 5) && DigitCount == 16) 
     printf("MASTERCARD\n"); 
    else 
     printf("INVALID\n"); 
    return; 
} 

ответ

4
Digit = 2 * ((CardNumber % (10^i))/(10^(i - 1))); 

^ не является оператором мощности, но побитового XOR в C и C++. Как только i достигает 10, выражение 10^i становится равным нулю.


Кстати, для того, чтобы получить цифры от целого числа, то лучше избегать операций с плавающей точкой (floor, log10l). Возможный алгоритм может выглядеть так:

int DigitIndex = 0; 
while (CardNumber > 0) 
{ 
    int Digit = CardNumber % 10; 
    CardNumber /= 10; 

    // calculate check sum depending on parity of DigitIndex 

    DigitIndex++;  
} 
+0

О, SNAP! Большое спасибо – RonaldMunodawafa

+0

@ user295341 Помимо этой проблемы, весь подход выглядит не так. Если вам нужно получить цифры целого числа, избегайте арифметики с плавающей точкой. Он просто просит неприятностей. Гораздо лучше получить цифру справа налево с повторением '% 10' и'/10'. – AlexD

+0

Это именно то, что делает цикл, при условии, что исправление выполнено. – RonaldMunodawafa

Смежные вопросы