001 /* JAPI - (Yet another (hopefully) useful) Java API 002 * 003 * Copyright (C) 2006 Christian Hujer 004 * 005 * This program is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU General Public License as 007 * published by the Free Software Foundation; either version 2 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, but 011 * WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * General Public License for more details. 014 * 015 * You should have received a copy of the GNU General Public License 016 * along with this program; if not, write to the Free Software 017 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 018 * 02111-1307, USA. 019 */ 020 021 package net.sf.japi.io; 022 023 /** A class with methods for converting BCD data from and to Binary data. 024 * Currently only int is supported. 025 * Probably <code>net.sf.japi.io</code> is not the ideal package for this class, yet it seems most appropriate. 026 * @author <a href="mailto:chris@riedquat.de">Christian Hujer</a> 027 */ 028 public final class BCD { 029 030 /** Private constructor - no instances needed. */ 031 private BCD() { 032 } 033 034 /** Convert a BCD value to an int value. 035 * @param bcd BCD value 036 * @return int value for bcd value 037 */ 038 public static int bcd2int(final int bcd) { 039 int ret = 0; 040 for (int i = 0; i < 8; i++) { 041 ret += (0xF & bcd >> 4 * i) * base10(i); 042 } 043 return ret; 044 } 045 046 /** Convert an int value to a BCD value. 047 * @param val int value 048 * @return bcd value for int value 049 */ 050 public static int int2bcd(final int val) { 051 int bcd = 0; 052 int work = val; 053 for (int i = 0; i < 8; i++) { 054 final int nibble = work % 10; 055 work /= 10; 056 bcd += nibble * (1 << 4 * i); 057 } 058 return bcd; 059 } 060 061 /** Check wether a BCD value is correct. 062 * If the supplied value contains a nibble with a value >= 10, it will throw an IllegalArgumentException. 063 * Otherwise it will simply return. 064 * @param bcd number to check 065 */ 066 public static void check(final int bcd) { 067 for (int i = 0; i < 8; i++) { 068 if ((0xF & bcd >> 4 * i) >= 10) { 069 throw new IllegalArgumentException(); 070 } 071 } 072 } 073 074 /** Check wether a BCD value is correct. 075 * @param bcd bcd value to check 076 * @return <code>true</code> if supplied value is bcd, otherwise <code>false</code> 077 */ 078 public static boolean isBcd(final int bcd) { 079 for (int i = 0; i < 8; i++) { 080 if ((0xF & bcd >> 4 * i) >= 10) { 081 return false; 082 } 083 } 084 return true; 085 } 086 087 /** Return the 10 base (10^n). 088 * @param n power 089 * @return <code>10^<var>n</var></code> 090 */ 091 public static int base10(final int n) { 092 int ret = 1; 093 for (int i = 0; i < n; i++) { 094 ret *= 10; 095 } 096 return ret; 097 } 098 099 /** Perform a BCD correction. 100 * For each nibble that contains a value greater than or equal 10, the next nibble will be incremented. 101 * Any overflow is added to the low byte, so an overflow bcd value will toggle even/odd. 102 * @param bcd bcd value to correct 103 * @return corrected bcd value 104 */ 105 public static int correct(final int bcd) { 106 int newBcd = bcd; 107 for (int i = 0; i < 8; i++) { 108 if ((0xF & bcd >> 4 * i) >= 10) { 109 newBcd -= 10 << 4 * i; 110 newBcd += 1 << 4 * (i + 1); 111 } 112 } 113 assert isBcd(newBcd); 114 return newBcd; 115 } 116 117 } // class BCD