Проблема в коде для присвоения CS50 CREDIT - PullRequest
0 голосов
/ 27 мая 2020

Я пытаюсь написать код для проблемы кредита, установленной в CS50 (кредит), я в самом начале, но вот проблема, с которой я столкнулся. Прямо сейчас я пытаюсь извлечь цифры карты, чтобы работать с ними позже, и проверяю, прошло ли извлечение хорошо. Кажется, что код работает для каждого di git в номере карты, кроме 12-го (начиная с конца).

например, номер карты: вход: 1111111111111111 выход: 1111111111101111

Хотя в некоторых случаев, когда эта проблема не возникает:

ввод: 1234567890123456 вывод: 1234567890123456

Вот мой код (пожалуйста, не будьте слишком сложными sh, я новичок ie: )) Я знаю, что есть другие способы получить эти цифры, но я действительно хочу понять, почему это не работает. Заранее спасибо!

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

long card_no(void);
int main(void)
{
    long card = card_no();
    int one = (card % 10);
    int two = (card % 100 - card % 10) * 0.1;
    int tree = (card % 1000 - card % 100) * 0.01;
    int four = (card % 10000 - card % 1000) * 0.001;
    int five = (card % 100000 - card % 10000) * 0.0001;
    int six = (card % 1000000 - card % 100000) * 0.00001;
    int seven = (card % 10000000 - card % 1000000) * 0.000001;
    int eight = (card % 100000000 - card % 10000000) * 0.0000001;
    int nine = (card % 1000000000 - card % 100000000) * 0.00000001;
    int ten = (card % 10000000000 - card % 1000000000) * 0.000000001;
    int eleven = (card % 100000000000 - card % 10000000000) * 0.0000000001;
    int twelve = (card % 1000000000000 - card % 100000000000) * 0.00000000001;
    int thirteen = (card % 10000000000000 - card % 1000000000000) * 0.000000000001;
    int forteen = (card % 100000000000000 - card % 10000000000000) * 0.0000000000001;
    int fifteen = (card % 1000000000000000 - card % 100000000000000) * 0.00000000000001;
    int sixteen = (card % 10000000000000000 - card % 1000000000000000) * 0.000000000000001;

    printf("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i\n", sixteen, fifteen, forteen, thirteen, twelve, eleven, ten, nine, eight, seven, six, five, four, tree, two, one);

}

//Prompt user for 13 to 16 digits card number
long card_no(void)
{
    long n;
    do
    {
       n = get_long("Card number:\n"); 
    }
    while (n < 1000000000000 || n > 9999999999999999);
    return n;
}

Ответы [ 2 ]

1 голос
/ 27 мая 2020

Математика с плавающей запятой неточна - такие значения, как 0.1, не могут быть представлены точно в конечном количестве бит, поэтому вы получаете только приближение, например 0.099... или 0.1000...1 или что-то вроде который. Итак, после выполнения математических расчетов для вашего пятого di git вы получите значение 0.9..., которое дает 0 при преобразовании в int.

Другой вариант, который не полагается на математику с плавающей запятой, - это разделить число, увеличив величину и взяв % 10 результата. IOW,

(123 /   1) % 10  == 123 % 10 == 3
(123 /  10) % 10  ==  12 % 10 == 2
(123 / 100) % 10  ==   1 % 10 == 1

Целочисленное деление дает целочисленный результат - любая дробная часть отбрасывается.

Подсказка, когда вы обнаруживаете, что создаете группу переменных одного типа с порядковыми именами (first, second, third или one, two, three) это действительно сильный намек на то, что вы хотите использовать массив :

#define  NUM_DIGITS 16
int digits[NUM_DIGITS];

/** 
 * get card number as before
 */

long magnitude = 1;
/**
 * Arrays are indexed from 0 to N-1
 */
for ( size_t i = 0; i < NUM_DIGITS; i++ ) 
  digits[i] = (card / magnitude) % 10;
  magnitude *= 10;
}

/**
 * I typically use size_t for array indices, which is an unsigned type.
 * This means it cannot represent negative values.  If we loop while "i >= 0",
 * then the loop will never exit, since subtracting 1 from 0 will "wrap
 * around" to the largest value.  So even though the array is indexed from
 * NUM_DIGITS-1 to 0, we loop over NUM_DIGITS to 1 and subtract 1 from 
 * i in the subscript operation.
 */
for ( size_t i = NUM_DIGITS; i > 0; i-- ) 
  printf( "%d", digits[i-1] );
0 голосов
/ 27 мая 2020

Этот небольшой фрагмент кода может показать вам НАМНОГО более простой способ начать работу.
Он извлекает все цифры числа, по одной, без использования все более гигантских c чисел, таких как 10000000.

#include <stdio.h>

int main(void) {
    unsigned long card_number = 564879165464;
    int counter = 1;

    while(card_number)
    {
        printf("Digit %d = %d\n", counter++, card_number % 10);
        card_number /= 10;
    }

    return 0;
}

Выход

Digit 1 = 4
Digit 2 = 6
Digit 3 = 4
Digit 4 = 5
Digit 5 = 6
Digit 6 = 1
Digit 7 = 9
Digit 8 = 7
Digit 9 = 8
Digit 10 = 4
Digit 11 = 6
Digit 12 = 5
...