by Neal R. Wagner
Copyright © 2001 by Neal R. Wagner. All rights reserved.
NOTE: This site is obsolete. See book draft (in PDF):
Here is the mod 97 scheme used for extra error detection. The check below tests its performance for adjacent double error detection. One expects this check to catch apprximately 99% of all random errors. However, it catches 99.94% of all adjacent double errors (except for possible adjacent double errors involving one of the two decimals representing the check "digit" and the first actual data digit).
// ErrorDetection.java: base class for single-digit error detection
public class ErrorDetection {
public static void printArray(int[] a) {
for (int i = 0; i < a.length; i++) {
if (a[i] == 10)
System.out.print("X ");
else
System.out.print(a[i]);
if (i%5 == 0) System.out.print(" ");
}
System.out.println();
}
public static void printUnchecked(int[] a) {
System.out.print("? ");
for (int i = 1; i < a.length; i++) {
System.out.print(a[i]);
if (i%5 == 0) System.out.print(" ");
}
System.out.println();
}
}
// Mod97ErrorDetection.java: Implement the mod 97 check for error detection
// uses successive powers of 10 (modulo 97) for the weights
public class Mod97ErrorDetection extends ErrorDetection {
public static int insertCheck(int[] a) {
int check = 0;
int weight = 10;
for (int i = 1; i < a.length; i++) {
check = (check + weight*a[i])%97;
weight = (weight*10)%97;
}
if (check == 0) a[0] = 0;
else a[0] = -check + 97;
return a[0];
}
public static boolean doCheck(int[] a) {
int check = 0;
int weight = 1;
for (int i = 0; i < a.length; i++) {
check = (check + weight*a[i])%97;
weight = (weight*10)%97;
}
if (check != 0) return false;
else return true;
}
// main function
public static void main (String[] args) {
int[] a = new int[100];
boolean checkFlag = false;
// no need for a random start
for (int i = 1; i < a.length; i++)
a[i] = (int)(Math.random() * 10.0);
// try all adjacent double errors
int errorCount = 0;
int totalCount = 0;
// try each successive position (all the same)
for (int pos = 1; pos < 99; pos++)
// try every pair of digits for the initial pair
for (int p1 = 0; p1 < 10; p1++)
for (int p2 = 0; p2 < 10; p2++) {
// insert the initial pair
a[pos] = p1; a[pos+1] = p2;
// do the check and insert mod 97 check "digit"
Mod97ErrorDetection.insertCheck(a);
// try every pair of digits for the double error
for (int n1 = 0; n1 < 10; n1++)
for (int n2 = 0; n2 < 10; n2++)
// only try if an actual change
if (n1 != p1 || n2 != p2) {
totalCount++;
// insert new air as an error
a[pos] = n1; a[pos+1] = n2;
// check if the change is not detected
if (Mod97ErrorDetection.doCheck(a)) {
System.out.println("Error, old digits: " +
p1 + p2 + ", new digits: " + n1 + n2 +
". Position: " + pos);
errorCount++;
}
}
}
System.out.println("Adjacent double errors undetected: " +
errorCount + ", out of " + totalCount + ", or " +
((double)errorCount/totalCount*100) + "%");
} // end of main
}
The error rate is 0.060606...%, or the equation catches 99.94 % of all adjacent double errors.
Error, old digits: 00, new digits: 79. Position: 1 Error, old digits: 10, new digits: 89. Position: 1 Error, old digits: 20, new digits: 99. Position: 1 Error, old digits: 79, new digits: 00. Position: 1 Error, old digits: 89, new digits: 10. Position: 1 Error, old digits: 99, new digits: 20. Position: 1 (similar entries for Position = 2, 3, ..., 98) Adjacent double errors undetected: 588, out of 970200, or 0.06060606060606061%