Java tutorial
//package com.java2s; /* * Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2007. * * Licensed under the Aduna BSD-style license. */ import java.util.StringTokenizer; public class Main { public static boolean isValidDecimal(String value) { try { normalizeDecimal(value); return true; } catch (IllegalArgumentException e) { return false; } } /** * Normalizes a decimal to its canonical representation. For example: * <tt>120</tt> becomes <tt>120.0</tt>, <tt>+.3</tt> becomes <tt>0.3</tt>, * <tt>00012.45000</tt> becomes <tt>12.45</tt> and <tt>-.0</tt> becomes * <tt>0.0</tt>. * * @param decimal * The decimal to normalize. * @return The canonical representation of <tt>decimal</tt>. * @throws IllegalArgumentException * If one of the supplied strings is not a legal decimal. */ public static String normalizeDecimal(String decimal) { decimal = collapseWhiteSpace(decimal); int decLength = decimal.length(); StringBuilder result = new StringBuilder(decLength + 2); if (decLength == 0) { throwIAE("Not a legal decimal: " + decimal); } boolean isZeroPointZero = true; // process any sign info int idx = 0; if (decimal.charAt(idx) == '-') { result.append('-'); idx++; } else if (decimal.charAt(idx) == '+') { idx++; } if (idx == decLength) { throwIAE("Not a legal decimal: " + decimal); } // skip any leading zeros while (idx < decLength && decimal.charAt(idx) == '0') { idx++; } // Process digits before the dot if (idx == decLength) { // decimal consists of zeros only result.append('0'); } else if (idx < decLength && decimal.charAt(idx) == '.') { // no non-zero digit before the dot result.append('0'); } else { isZeroPointZero = false; // Copy any digits before the dot while (idx < decLength) { char c = decimal.charAt(idx); if (c == '.') { break; } if (!isDigit(c)) { throwIAE("Not a legal decimal: " + decimal); } result.append(c); idx++; } } result.append('.'); // Process digits after the dot if (idx == decLength) { // No dot was found in the decimal result.append('0'); } else { idx++; // search last non-zero digit int lastIdx = decLength - 1; while (lastIdx >= 0 && decimal.charAt(lastIdx) == '0') { lastIdx--; } if (idx > lastIdx) { // No non-zero digits found result.append('0'); } else { isZeroPointZero = false; while (idx <= lastIdx) { char c = decimal.charAt(idx); if (!isDigit(c)) { throwIAE("Not a legal decimal: " + decimal); } result.append(c); idx++; } } } if (isZeroPointZero) { // Make sure we don't return "-0.0" return "0.0"; } else { return result.toString(); } } /** * Replaces all contiguous sequences of #x9 (tab), #xA (line feed) and #xD * (carriage return) with a single #x20 (space) character, and removes any * leading and trailing whitespace characters, as specified for whiteSpace * facet <tt>collapse</tt>. */ public static String collapseWhiteSpace(String s) { StringBuilder sb = new StringBuilder(s.length()); StringTokenizer st = new StringTokenizer(s, "\t\r\n "); if (st.hasMoreTokens()) { sb.append(st.nextToken()); } while (st.hasMoreTokens()) { sb.append(' ').append(st.nextToken()); } return sb.toString(); } /** * Throws an IllegalArgumentException that contains the supplied message. */ private static final void throwIAE(String msg) { throw new IllegalArgumentException(msg); } /** * Checks whether the supplied character is a digit. */ private static final boolean isDigit(char c) { return c >= '0' && c <= '9'; } }