Signed overpunch is a format used to store the positive or negative sign of a number without using a “+” or “-“ character by changing the last digit. Frequently used in fixed-width format text files to prevent the spacing from being changed due to the addition of a plus or minus sign.
Example field description: S9(6)V99
S
- Leading sign9(5)
- 6 decimal digitsV
- Implied decimal point99
- 2 digits after the implied decimal point
Implemented in PHP (could probably be done more elegantly):
function parse_overpunch($data, $digitsAfterDecimal=2){
$last = substr($data, -1);
$negative = array_search($last, ['{','A','B','C','D','E','F','G','H','I']) === false;
switch ($last) {
case '{': $data = substr_replace($data, 0, -1); break;
case 'A': $data = substr_replace($data, 1, -1); break;
case 'B': $data = substr_replace($data, 2, -1); break;
case 'C': $data = substr_replace($data, 3, -1); break;
case 'D': $data = substr_replace($data, 4, -1); break;
case 'E': $data = substr_replace($data, 5, -1); break;
case 'F': $data = substr_replace($data, 6, -1); break;
case 'G': $data = substr_replace($data, 7, -1); break;
case 'H': $data = substr_replace($data, 8, -1); break;
case 'I': $data = substr_replace($data, 9, -1); break;
case '}': $data = substr_replace($data, 0, -1); break;
case 'J': $data = substr_replace($data, 1, -1); break;
case 'K': $data = substr_replace($data, 2, -1); break;
case 'L': $data = substr_replace($data, 3, -1); break;
case 'M': $data = substr_replace($data, 4, -1); break;
case 'N': $data = substr_replace($data, 5, -1); break;
case 'O': $data = substr_replace($data, 6, -1); break;
case 'P': $data = substr_replace($data, 7, -1); break;
case 'Q': $data = substr_replace($data, 8, -1); break;
case 'R': $data = substr_replace($data, 9, -1); break;
default: break;
}
// ex. "000000000" after swapping in overpunch digit
if($data == 0){
return 0;
}
$data = substr_replace($data, '.', -$digitsAfterDecimal, 0);
return $negative ? -$data : ltrim($data, '0');
}