Reputation: 19
I'm trying to calculate any ISBN-13 Number's Check Digit, I'm not too worried if the ISBN number is valid or invalid, but what I've been trying to do is get the code to work. There are obviously flaws in my interpretation of the algorithm, suggestions on how to fix it are welcome but the primary problem is receiving user input that is too large for an integer variable but I also want to avoid the decimals of the double value.
I already tried to use the BigDecimal
and BigNumber
but I simply don't have enough experience to be able to understand them completely. This is the algorithm to find d13 (the Check Digit): 10-(d1 +3d2 +d3 +3d4 +d5 +3d6 +d7 +3d8 +d9 +3d10 +d11 +3d12)%10.
The Code is a mess I know. I've used this website as a reference to what I want to do and I've been using this ISBN number as my practice: 9780132130806
.
Again my question is how can I print the final ISBN number without decimals and how can I possibly fix my algorithm? (I'd also really appreciate any tips on a website that helps with teaching JOption as that is the prefered method i use because it looks a bit cleaner to me than using the scanner)
import javax.swing.JOptionPane;
import java.math.BigInteger;
public class ISBN
{
//George Sayegh Calculate check Digit ISBN
public static void main(String[] args)
{
//Define Variables
double ISBN12, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12 = 0, D13;
double A = 100000000000L;
double B = 10000000000L;
double C = 1000000000;
double D = 100000000;
double E = 10000000;
double F = 1000000;
double G = 100000;
double H = 10000;
double I = 1000;
double J = 100;
double K = 10;
double L = 1;
//Get ISBN #
String ISBN12text = JOptionPane.showInputDialog("Please enter the first 12 digits of your ISBN number");
ISBN12 = Double.parseDouble(ISBN12text);
//Calculate D1
D1 = ((ISBN12 - (ISBN12 % A)) / A);
//Calculate D2
D2 = ((ISBN12 - (ISBN12 % B)) / B);
//Calculate D3
D3 = ((ISBN12 - (ISBN12 % C)) / C);
//Calculate D4
D4 = ((ISBN12 - (ISBN12 % D)) / D);
//Calculate D5
D5 = ((ISBN12 - (ISBN12 % E)) / E);
//Calculate D6
D6 = ((ISBN12 - (ISBN12 % F)) / F);
//Calculate D7
D7 = ((ISBN12 - (ISBN12 % G)) / G);
//Calculate D8
D8 = ((ISBN12 - (ISBN12 % H)) / H);
//Calculate D9
D9 = ((ISBN12 - (ISBN12 % I)) / J);
//Calculate D10
D10 = ((ISBN12 - (ISBN12 % K)) / K);
//Calculate D11
D11 = ((ISBN12 - (ISBN12 % L)) / L);
//Get D13
D13 = 10 - (D1 + (3 * D2) + D3 + 3 * D4 + D5 + 3 * D6 + D7 + 3 * D8 + D9 + 3 * 10 + D11 + 3 * D12) % 10;
JOptionPane.showMessageDialog(null, D1 +""+ D2 +""+ D3 +""+ D4 +""+ D5 +""+ D6 +""+ D7 +""+ D8 +""+ D9 +""+ D10 +""+ D11 +""+ D12 +""+ 13);
}
}
Upvotes: 0
Views: 3134
Reputation: 7579
Try this extremely simple algorithm (written in Python, but it should be very easy to convert to Java). The comments hopefully explain enough. Should convert to not more than 10 lines (not including blank lines for readability)
# Valid ISBN-12 string from user (12 numbers, doesn't matter what other characters)
isbn12 = '978-0-306-40615' # Input it from the user, hardcoded Wikipedia example for testing
coeff = 1 # Multiple used in calculating sum
sum = 0
for d in isbn12: # Equivalent to for(char d : isbn12.toCharArray())
# this next block is just a tryParse or an isDigit check
# if the character is a digit, parse it to an int
# else continue to next iteration
try:
# just reassigning the value because-
# Hey, this is Python!
d = int(d)
except ValueError:
continue
# Add to sum after multiplying with coeff
sum += d * coeff
# If coeff was 1, change to 3 and vice versa
# Equivalent to coeff == 1 ? 3 : 1 in Java
coeff = 3 if coeff == 1 else 1
# END FOR LOOP
# Get positive number to be added to make ISBN divisible by 10
# The extra % 10 at the end is for changing 10 to 0 without if
check_digit = (10 - sum % 10) % 10
Upvotes: 2
Reputation: 4845
Here's a much simpler implementation based on this Wikipedia example. It lacks sanity checks---such as whether the input string is a valid ISBN13---but should be enough to get you going. I hope it helps.
Note that the input is an ISBN-13 string with the check digit removed (e.g. 978013213080
instead of 9780132130806
); the program prints the check digit on the output; you should be able modify it if this is not what you want.
public class CheckISBN13 {
/* We assume isbnString is a *valid* ISBN-13 with the check digit removed. */
public static int[] stringToInt(String isbnString) {
int[] isbnInt = new int[12];
int j = 0;
for (int i = 0; i < isbnString.length(); ++i) {
if (Character.isDigit(isbnString.charAt(i))) {
isbnInt[j++] = Character.getNumericValue(isbnString.charAt(i));
}
}
return isbnInt;
}
public static int getCheckDigit(int[] isbnInt) {
int val = 0;
for (int i = 0; i < isbnInt.length; ++i) {
int coeff = (i % 2 == 0 ? 1 : 3);
val += coeff * isbnInt[i];
}
return 10 - (val % 10);
}
public static void main(String[] args) {
if (args.length < 1) {
System.err.println("Usage: java CheckISBN13 978-0-306-40615");
System.exit(-1);
}
String isbnString = args[0];
int[] isbnInt = stringToInt(isbnString);
System.out.println("Check digit: " + getCheckDigit(isbnInt));
}
}
Upvotes: 2