Skip to main content

OverpunchFormat - Java class


OverpunchFormat is a subclass of DecimalFormat that formats decimal numbers into NSF Overpunch Format.


The purpose of an Overpunch format is to encode the sign (+/-) into the least significant (right-most) digit via an encoding scheme. Also the values are typically dollar amounts, and therefore are integers representing cents (1/100 dollar). The use of DecimalFormat's setMultipler method will make quick work of this scaling.

Get the Java source code for OverpunchFormat.java.

OverpunchFormat is a subclass of DecimalFormat that formats decimal numbers into NSF Overpunch Format.

The purpose of an Overpunch format is to encode the sign (+/-) into the least significant (right-most) digit via an encoding scheme. Also the values are typically dollar amounts, and therefore are integers representing cents (1/100 dollar). The use of DecimalFormat's setMultipler method will make quick work of this scaling.


//package name.koontz.util;

import java.io.Serializable;
import java.text.NumberFormat;
import java.text.ParsePosition;
import java.text.FieldPosition;
//import java.lang.Number;
//import java.lang.StringBuffer;
import java.text.*;


/**
* OverpunchFormat is a subclass of DecimalFormat that formats
* decimal numbers into NSF Overpunch Format.
*
* The purpose of an Overpunch format is to encode the sign (+/-) into the
* least significant (right-most) digit via an encoding scheme.  Also the values are
* typically dollar amounts, and therefore are integers representing cents
* (1/100 dollar). The use of the setMultipler method will make quick work of
* this scaling.
*
*

*
* Holy hanging chad! Batman, the bat computer has detected an
* overpunched field, what could it mean?
*
* Well, Robin, it means the Joker has saved a byte in transmition cost, but it
* will take the bat computer only 23 instructions to figure out what this sign
* could be...
*

*

*
*
* OverpunchFormat does not support locales, itself!  So do not expect Kanji
* characters in your overpunched output.
*
*
*

Overpunch Encoding

*


*             Least
*          Significant   Positive      Negative
*             Digit     Overpunch     Overpunch
*               0           {             }
*               1           A             J
*               2           B             K
*               3           C             L
*               4           D             M
*               5           E             N
*               6           F             O
*               7           G             P
*               8           H             Q
*               9           J             R
*
*

*
* Example:
*

* -1575  =>  157N
* +1200  =>  120{
*

*
*
* If OverpunchFormat.parse(String, ParsePosition) fails to parse a string, it
* returns null, leaves the ParsePosition index unchanged, and sets the
* ParsePosition error index.
*
* A OverpunchFormat pattern contains only a postive pattern (no negative subpattern).
* Since the whole concept of an overpunched value is to
* encode the sign within the last digit, there will be no negative subpattern.
*
*
* Note:  DecimalFormat JVM 1.2.2 bugs Sun Bug Id 4322804, 4254220, 4243108
*
*
* @see Format
* @see NumberFormat
* @see DecimalFormat
* @see ParsePosition
*/
public class OverpunchFormat extends java.text.DecimalFormat
    implements Cloneable, Serializable  {

    // array of overpunch replacement characters
    private static final char[] positiveDigit = {'{', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'};
    //                          overpunch digit   0    1    2    3    4    5    6    7    8    9
    private static final char[] negativeDigit = {'}', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R'};


    public OverpunchFormat() {
        super();
    }

    public OverpunchFormat(String pattern) throws IllegalArgumentException  {
        super(pattern);
        //
    }

    /**
     * Returns an instance of Number with a value matching the given string.
     *
     *
     * @param text                the string to be parsed
     * @param parsePosition       on entry, where to begin parsing; on exit, just past the last parsed character. If parsing fails, the index will not move and the error index will be set.
     * @return                    the parsed value, or null if the parse fails
     */
    public Number parse(String text, ParsePosition parsePosition) {
        //
        int sign = 1;  // or -1 if negative
        char lastDigit;
        char overpunchChar = '{';
        int overpunchIndex = 0;

        // start at the parsePosition within text - look for a non-numeric char
        // that's the overpunch char
        if ( parsePosition.getIndex() < text.length() ) {
            for (int i = parsePosition.getIndex(); i < text.length(); i++) {
                char c = text.charAt(i);
                if ( Character.getType(c) == Character.DECIMAL_DIGIT_NUMBER ) {
                    continue;
                } else {
                    // found first non digit char - that's the overpunch
                    overpunchChar = c;
                    overpunchIndex = i;
                    break;
                }
            }
        }

        // reverse the overpunch

        switch (overpunchChar) {
        case  '}':
             sign = -1;
             lastDigit = '0';
             break;
        case  '{':
             sign = 1;
             lastDigit = '0';
             break;
        case  'A':
             sign = 1;
             lastDigit = '1';
             break;
        case  'B':
             sign = 1;
             lastDigit = '2';
             break;
        case  'C':
             sign = 1;
             lastDigit = '3';
             break;
        case  'D':
             sign = 1;
             lastDigit = '4';
             break;
        case  'E':
             sign = 1;
             lastDigit = '5';
             break;
        case  'F':
             sign = 1;
             lastDigit = '6';
             break;
        case  'G':
             sign = 1;
             lastDigit = '7';
             break;
        case  'H':
             sign = 1;
             lastDigit = '8';
             break;
        case  'I':
             sign = 1;
             lastDigit = '9';
             break;
        case  'J':
             sign = -1;
             lastDigit = '1';
             break;
        case  'K':
             sign = -1;
             lastDigit = '2';
             break;
        case  'L':
             sign = -1;
             lastDigit = '3';
             break;
        case  'M':
             sign = -1;
             lastDigit = '4';
             break;
        case  'N':
             sign = -1;
             lastDigit = '5';
             break;
        case  'O':
             sign = -1;
             lastDigit = '6';
             break;
        case  'P':
             sign = -1;
             lastDigit = '7';
             break;
        case  'Q':
             sign = -1;
             lastDigit = '8';
             break;
        case  'R':
             sign = -1;
             lastDigit = '9';
             break;
        default:
             // not the overpunch char - error
             parsePosition.setErrorIndex(overpunchIndex);
             return null;  // error return null

        }

        // replace with the overpunch char in text with the digit
        StringBuffer sb = new StringBuffer(text);

        sb.setCharAt(overpunchIndex, lastDigit);

        // now call the super's function
        Number n = super.parse(sb.toString(), parsePosition);

        if ( n instanceof Double ) {
            double d = n.doubleValue();
            d = d * sign;
            n = new Double(d);
        } else if ( n instanceof Long ) {
            long l = n.longValue();
            l = l * sign;
            n = new Long(l);
        } else {
            ;  // nothing
        }

        return n;
    }

    /**
     * Formats a long to produce a string.
     *
     * @param number               the long to format
     * @param result               where the text is to be appended
     * @param fieldPosition        On input: an alignment field, if desired. On output: the offsets of the alignment field.
     * @return                     The value passed in as the result parameter
     */
    public StringBuffer format(long number, StringBuffer result, FieldPosition fieldPosition) {
//System.out.println("OverpunchFormat.format|long number");
//System.out.println("OverpunchFormat.format( "+number+", "+result.toString()+", "+fieldPosition+" )");
        //
        StringBuffer buf = new StringBuffer(result.length()+20);
        long abs = Math.abs(number);          // get the absolute value
//System.out.println("    abs = "+abs);

        // call DecmialFormat to format all but the overpunch
        buf = super.format(abs, result, fieldPosition);
//System.out.println("    super.format() returns buf = " + buf.toString());
        // now we must workout the overpunch
        //
        // get last digit of the string
        char overpunchChar = buf.charAt(buf.length()-1);
//System.out.println("    buf.length()-1 = " + (buf.length()-1));
//System.out.println("    overpunchChar = " + overpunchChar);
        // convert last digit to index into the overpunch (+/-) array
        int overpunchIndex = Character.getNumericValue(overpunchChar);
//System.out.println("    overpunchIndex = " + overpunchIndex);
        // get overpunch char
        if ( number < 0 ) {
            overpunchChar = negativeDigit[overpunchIndex];
        } else {
            overpunchChar = positiveDigit[overpunchIndex];
        }
//System.out.println("    overpunchChar = " + overpunchChar);
        // replace the lastChar in the string with new lastChar
        buf.deleteCharAt(buf.length()-1);
        buf.append(overpunchChar);
//System.out.println("    buf = " + buf.toString());

        return buf;
    }

    /**
     * Formats a double to produce a string.
     *
     * @param number               the double to format
     * @param result               where the text is to be appended
     * @param fieldPosition        On input: an alignment field, if desired. On output: the offsets of the alignment field.
     * @return                     The value passed in as the result parameter
     */
    public StringBuffer format(double number, StringBuffer result, FieldPosition fieldPosition) {
//System.out.println("OverpunchFormat.format|double number");
//System.out.println("OverpunchFormat.format( "+number+", "+result.toString()+", "+fieldPosition+" )");
        //
        StringBuffer buf = new StringBuffer(result.length()+20);
        double abs = Math.abs(number);          // get the absolute value
//System.out.println("    abs = "+abs);

        // call DecmialFormat to format all but the overpunch
        buf = super.format(abs, result, fieldPosition);
//System.out.println("    super.format() returns buf = " + buf.toString());

        // now we must workout the overpunch
        //
        // get last digit of the string
        char overpunchChar = buf.charAt(buf.length()-1);
//System.out.println("    buf.length()-1 = " + (buf.length()-1));
//System.out.println("    overpunchChar = " + overpunchChar);

        // convert last digit to index into the overpunch (+/-) array
        int overpunchIndex = Character.getNumericValue(overpunchChar);
//System.out.println("    overpunchIndex = " + overpunchIndex);

        // get overpunch char
        if ( number < 0 ) {
            overpunchChar = negativeDigit[overpunchIndex];
        } else {
            overpunchChar = positiveDigit[overpunchIndex];
        }
//System.out.println("    overpunchChar = " + overpunchChar);

        // replace the lastChar in the string with new lastChar
        buf.deleteCharAt(buf.length()-1);
        buf.append(overpunchChar);
//System.out.println("    buf = " + buf.toString());


        return buf;
    }



    /**
     *  The main program for the class - a test method.
     *
     *@param  args  the text to parse
     */
    public static void main(String[] args) {

        OverpunchFormat of = new OverpunchFormat();
        of.applyPattern("0000000"); // fixed field zero padded
        of.setMultiplier(100);      // imply 2 decimal places

        if (args.length < 2) {
            System.out.println("Usage: java OverpunchFormat 'pattern' 'value'");
            System.out.println("Examples format():");
            System.out.println("  9876      -> " +of.format(9876l));
            System.out.println("    -1.35   -> " +of.format(-1.35));
            System.out.println("      .2389 -> " +of.format(0.2389));
            System.out.println("note; fixed field zero padding, implied decimal place, rounding and encoding");

            StringBuffer sb = new StringBuffer("x=012345F dollars ");
            ParsePosition pos = new ParsePosition(2);
            System.out.println("Examples parse():");
            System.out.println("  before call:" + sb);
            System.out.println("  parse(sb, pos) where pos =" + pos);
            System.out.println("  parse returns a Number = " + of.parse(sb.toString(), pos));
            System.out.println("  and sets ParsePosition.index = " + pos.getIndex() + " & errorIndex = " + pos.getErrorIndex());


            System.exit(99);
        } else {
            StringBuffer sb = new StringBuffer("OverpunchFormat of "+ args[1] +" is ");
            of.applyPattern(args[0]);
            of.format(Double.valueOf(args[1]), sb, new FieldPosition(NumberFormat.FRACTION_FIELD) );

            System.out.println(sb.toString());

        }

    }


}


Post a Comment

Most Popular on Agile Complexification Inverter

Team Performance Model - by Drexler and Sibbet

Many of you have all heard of the Tuckman model of team dynamics (Forming, Storming, Norming, Performing).  It was created in 1966 and has become the most popular model for describing team behavior.  Is it time to level up in your mental model of team dynamics?  Are you ready for a richer more functional model?



Introducing the Team Performance Model by Drexler and Sibbet



Orientation - Why am I here?
"Orientation is about understanding the purpose of a team and assessing what it will mean to be a member.  you need to understand the reason the team exist, what will be expected of you and how you will benefit from membership.  In a new team, these are individual concerns, because the group is only potentially a team.  that is why these concerns are illustrated as occurring in your imagination at an intuitive level.  As a team leader it is important to provide time and space for people to answer these internal questions themselves."

Keys to when Orientation challenges are resolve…

Where is Shakespeare When We Need Him?

We are desperately searching for a term for people that connotes the best of human kind.  The creative, sensing, combinatorial synergistic, empathic solutioning persons that have yet to been labeled with a role name that works.

Some of the old terms:
Staff, Workforce, Human Resource, My Team, Army, Company

Shakespeare created 1700 words in his time.  He mutated verbs to nouns, and vice-a-versa, transformed verbs into adjectives, and formed words from whole cloth never before heard.  This skill is rare, but there is a poet that can create the term we need in the twenty-first century.

What should this term define?

21st Century Human Resource; the generalizing specialist.

Yes, but what more?  What less?

Suggest your poetry in the comments, let us see if we cannot do 1/1700 as well as The Bard.

By-the-way; who create the phrase "coin a word"?



A TED Play List - How do you create new words
6:52
Erin McKeanGo ahead, make up new words! In this fun, short talk from TEDYouth, lexicographer Er…

Software Development terms applied to Home Construction

Let's Invert the typically wrong headed view of Software Development project management as a construction project.  We can map it the other way just to see if it works... to have some fun, to explore the meaning of phrases we toss around quite frequently.


Normally Project Management terms come from a construction domain.  We are going to apply the lexicon of modern software to the construction of a home.  We will follow the construction project and meet some of the people doing the work.

This is a very small (8 homes from $600,000 skyward) program in my 30-40 year old neighborhood.

About 6 months ago I saw the programs landing page go up.  It gives casual observers and some of the stakeholders a general idea of the intent of the program.  And most importantly who to contact for additional information if you happen to be interested in their products.

The Refuge program has 8 product projects and has them running independently.  Yet much of their DevOps infrastructure has already b…

a little feedback please...

some feedback please...
How do you like the new look and feel of our site?
  ___)  nah (I like the old one better - bring it back)
  _X_)  yeah (much cleaner and easy to navigate)



powered by Typeform
See Also:

One Dark and Stormy during a Hurricane

I'm from the Carolina's where legend has it that our family commonly just hunkered down in the home on the coast and waterways than to head for inland shelter. Now that's from the old school days of barely improved (read paved) roads. They counted a storms severity by how high on the back porch steps (about 15 - top to ground) the water reached.  I don't recommend this action in todays world of long range forecast and transportation options.

I do recommend a drink or two in a hotel bar, far far away.

This is the week that Harvey came ashore in Texas.  I live on a hill in the little old town of Grapevine outside Dallas and Fort Worth.  And thank you all for letting me know that a storm is coming... I didn't get out and walk Malibu before the rain hit, so I grabbed a hat and we went anyway.  Much nicer walk with the drizzle, I'd say.

I'll raise a glass to you - if you were not smart enough to do the responsible thing, at the last responsible moment.

I do re…