Basic C programming question
Hi,
I am taking the Harvard CS50 online course. The programme is to check credit card number validity. Why does the checkfunction() fail with a floating point error, when tested with a valid Mastercard number? I also tried using gdb, but it gave an error to do with get_long being not declared. Any other comments on how to improve the code very welcome. NB. I'm not sure if the maths works yet... Code:
#include <cs50.h> |
Line 40
Code:
x = get_long("Number: "); |
In the wrong place / incorrectly assigned?
|
I downloaded that header file from here
https://raw.githubusercontent.com/cs...ain/src/cs50.h I included it with Code:
gcc test.c -o test -I/home/me/ Code:
gcc test.c -o test -I/home/me/ |
I replaced:
Code:
//x = get_long("Number: "); Code:
./test |
Quote:
|
Use of those floating point literals makes me nervous. Not all numbers can be represented as a floating point value and using them forces the implicit conversion of 'x' into a double for any expressions using one of them as an operand. Much safer to stick with longs.
The first positive integer number that is unrepresentable as a 64bit double is over 9e+15, so most card numbers are likely safe, but "1e16 - 1" might not be! Lets see... Code:
$ cat float.c So, if your only goal for using the exponent form is to make the code more readable by avoiding those long numbers cluttering up your expressions then you'd be much better off using a macro instead, something like: #define L_1e14 100000000000000L This will keep the code readable while avoiding all the nastiness that using floating point operations introduces. |
Quote:
For the purpose of testing, a scanf("%ld", &x); will likely suffice. |
Quote:
Code:
$ ./check-credit Quote:
Code:
Program received signal SIGFPE, Arithmetic exception. |
I would design this function to use a string input which it parses character by character, converting each to a digit with x = ord(ch) - ord('0'); after testing that the character is, in fact, a digit. This would allow the input of spaces which the loop could simply ignore. You can count the digits to ensure that the length is correct.
Your code as-written assumes that a credit card number can be represented as long but this is not a valid assumption. |
Quote:
https://github.com/cs50/libcs50/blob/v11.0.1/src/cs50.c Line 369 |
Ok, to put all of that into one c file, so that you can look at it, and study it, without the need to include header files from a different location, and to see what it is doing.
aaa.c Code:
#include <stdio.h> Code:
gcc aaa.c -o aaa Code:
./aaa |
Let me kindly repeat: your true input is a string, which must consist of digit-characters and spaces, and which must contain a specified number of digit-characters. Do not try to use a library call to convert this input into "an integer" of whatever length, because in the general case it will not work. You need to step back and reconsider your entire approach.
|
Code:
$ diff -u cs50.bak cs50.c |
All times are GMT -5. The time now is 02:19 PM. |