OceanusDecimalParser.java
/*******************************************************************************
* Oceanus: Java Utilities
* Copyright 2012,2025 Tony Washer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package net.sourceforge.joceanus.oceanus.decimal;
import java.util.Currency;
import java.util.Locale;
/**
* Parsing methods for decimals in a particular locale.
* @author Tony Washer
*/
public class OceanusDecimalParser {
/**
* Parse Error message.
*/
private static final String ERROR_PARSE = "Non Decimal Numeric Value: ";
/**
* Bounds Error message.
*/
private static final String ERROR_BOUNDS = "Value out of range: ";
/**
* PerCent adjustment.
*/
public static final int ADJUST_PERCENT = 2;
/**
* PerMille adjustment.
*/
public static final int ADJUST_PERMILLE = 3;
/**
* The locale.
*/
private OceanusDecimalLocale theLocale;
/**
* Do we use strict # of decimals?
*/
private boolean useStrictDecimals = true;
/**
* Constructor.
*/
public OceanusDecimalParser() {
/* Use default locale */
this(Locale.getDefault());
}
/**
* Constructor.
* @param pLocale the locale
*/
public OceanusDecimalParser(final Locale pLocale) {
/* Store locale */
setLocale(pLocale);
}
/**
* Should we parse to strict decimals.
* @param bStrictDecimals true/false
*/
public void setStrictDecimals(final boolean bStrictDecimals) {
/* Set accounting mode on and set the width */
useStrictDecimals = bStrictDecimals;
}
/**
* Set the locale.
* @param pLocale the locale
*/
public final void setLocale(final Locale pLocale) {
/* Store the locale */
theLocale = new OceanusDecimalLocale(pLocale);
}
/**
* Obtain the default currency.
* @return the default currency
*/
public final Currency getDefaultCurrency() {
return theLocale.getDefaultCurrency();
}
/**
* Parse a string into a decimal.
* @param pValue The value to parse.
* @param pResult the decimal to hold the result in
* @throws IllegalArgumentException on invalid decimal
*/
protected static void parseDecimalValue(final String pValue,
final OceanusDecimal pResult) {
parseDecimalValue(pValue, OceanusDecimalFormatter.LOCALE_DEFAULT, false, pResult);
}
/**
* Parse a string into a decimal.
* @param pValue The value to parse.
* @param pLocale the Decimal locale
* @param useMoneyDecimal use money decimal rather than standard decimal true/false
* @param pResult the decimal to hold the result in
* @throws IllegalArgumentException on invalid decimal
*/
protected static void parseDecimalValue(final String pValue,
final OceanusDecimalLocale pLocale,
final boolean useMoneyDecimal,
final OceanusDecimal pResult) {
/* Handle null value */
if (pValue == null) {
throw new IllegalArgumentException();
}
/* Create a working copy */
final StringBuilder myWork = new StringBuilder(pValue.trim());
/* If the value is negative, strip the leading minus sign */
final boolean isNegative = (myWork.length() > 0)
&& (myWork.charAt(0) == pLocale.getMinusSign());
if (isNegative) {
myWork.deleteCharAt(0);
}
/* Remove any grouping characters from the value */
final String myGrouping = pLocale.getGrouping();
int myPos;
for (;;) {
myPos = myWork.indexOf(myGrouping);
if (myPos == -1) {
break;
}
myWork.deleteCharAt(myPos);
}
/* Trim leading and trailing blanks again */
trimBuffer(myWork);
/* Locate the exponent if present */
int myExponent = 0;
myPos = myWork.indexOf("e");
if (myPos != -1) {
/* Obtain the exponent and remove from decimals */
final String myExp = myWork.substring(myPos + 1);
myWork.setLength(myPos);
/* Parse the integral part */
try {
myExponent = Integer.parseInt(myExp);
} catch (NumberFormatException e) {
throw new IllegalArgumentException(ERROR_PARSE
+ pValue, e);
}
}
/* Locate the decimal point if present */
myPos = myWork.indexOf(useMoneyDecimal
? pLocale.getMoneyDecimal()
: pLocale.getDecimal());
/* Assume no decimals */
StringBuilder myDecimals = null;
int myScale = 0;
/* If we have a decimal point */
if (myPos != -1) {
/* Split into the two parts being careful of a trailing decimal point */
if ((myPos + 1) < myWork.length()) {
myDecimals = new StringBuilder(myWork.substring(myPos + 1));
}
myWork.setLength(myPos);
}
/* If we have a positive exponent */
if (myExponent > 0) {
/* Determine the number of decimals */
int myNumDec = myDecimals == null
? 0
: myDecimals.length();
/* Shift decimals across */
while (myExponent > 0 && myNumDec > 0) {
/* Copy decimal across */
final char myChar = myDecimals.charAt(0);
myDecimals.deleteCharAt(0);
myWork.append(myChar);
/* Adjust counters */
myExponent--;
myNumDec--;
}
/* Finish off with zeroes */
while (myExponent > 0) {
myWork.append(OceanusDecimalFormatter.CHAR_ZERO);
myExponent--;
}
/* If we now have no decimals remove decimal indication */
if (myNumDec == 0) {
myDecimals = null;
}
/* If we have a negative exponent */
} else if (myExponent < 0) {
/* Determine the number of integer digits */
int myNumDigits = myWork.length();
final StringBuilder myCopy = new StringBuilder();
/* Shift decimals across */
while (myExponent < 0 && myNumDigits > 0) {
/* Copy digit across */
final char myChar = myWork.charAt(myNumDigits - 1);
myWork.deleteCharAt(myNumDigits - 1);
myCopy.insert(0, myChar);
/* Adjust counters */
myExponent++;
myNumDigits--;
}
/* Finish off with zeroes */
while (myExponent < 0) {
myCopy.insert(0, OceanusDecimalFormatter.CHAR_ZERO);
myExponent++;
}
/* If we have decimals already */
if (myDecimals != null) {
myDecimals.insert(0, myCopy);
} else {
myDecimals = myCopy;
}
}
/* Handle leading decimal point on value */
if (myWork.length() == 0) {
myWork.append(OceanusDecimalFormatter.CHAR_ZERO);
}
/* Parse the integral part */
long myValue;
try {
myValue = Long.parseLong(myWork.toString());
} catch (NumberFormatException e) {
throw new IllegalArgumentException(ERROR_PARSE
+ pValue, e);
}
/* If we have a decimal part */
if (myDecimals != null) {
/* If we have too many decimals */
char myLastDigit = OceanusDecimalFormatter.CHAR_ZERO;
myScale = myDecimals.length();
if (myScale > OceanusDecimal.MAX_DECIMALS) {
/* Extract most significant trailing digit and truncate the value */
myLastDigit = myDecimals.charAt(OceanusDecimal.MAX_DECIMALS);
myDecimals.setLength(OceanusDecimal.MAX_DECIMALS);
myScale = myDecimals.length();
}
/* Adjust the value to make room for the decimals */
myValue *= OceanusDecimal.getFactor(myScale);
/* Parse the decimals */
try {
myValue += Long.parseLong(myDecimals.toString());
} catch (NumberFormatException e) {
throw new IllegalArgumentException(ERROR_PARSE
+ pValue, e);
}
/* Round value according to most significant discarded decimal digit */
if (myLastDigit >= Character.forDigit(OceanusDecimal.RADIX_TEN >> 1, OceanusDecimal.RADIX_TEN)) {
myValue++;
}
}
/* If the value is negative, negate the number */
if (isNegative) {
myValue = -myValue;
}
/* Store the result into the decimal */
pResult.setValue(myValue, myScale);
}
/**
* Adjust to desired decimals.
* @param pValue the value to adjust
* @param pDecimals the desired decimals
*/
private void adjustDecimals(final OceanusDecimal pValue,
final int pDecimals) {
/* If we are using strict decimals */
if (useStrictDecimals) {
/* Correct the scale */
pValue.adjustToScale(pDecimals);
/* else we should honour what we can */
} else {
/* Calculate the standard correction */
final int myAdjust = pDecimals
- pValue.scale();
/* If we have too few decimals */
if (myAdjust > 0) {
/* Adjust the value appropriately */
pValue.movePointLeft(myAdjust);
/* else if we have too many */
} else if (myAdjust < 0) {
/* remove redundant decimal places */
pValue.reduceScale(pDecimals);
}
}
}
/**
* Parse a string to extract currency information.
* @param pWork the buffer to parse
* @param pDeemedCurrency the assumed currency if no currency identifier
* @return the parsed currency
* @throws IllegalArgumentException on invalid currency
*/
private Currency parseCurrency(final StringBuilder pWork,
final Currency pDeemedCurrency) {
/* Look for a currency separator */
final int iPos = pWork.indexOf(OceanusDecimalFormatter.STR_CURRSEP);
if (iPos > -1) {
/* Extract currency detail and determine currency */
final String myCurr = pWork.substring(0, iPos);
pWork.delete(0, iPos + 1);
return Currency.getInstance(myCurr);
}
/* Set default currency */
Currency myCurrency = pDeemedCurrency;
final char myMinus = theLocale.getMinusSign();
/* If we have a leading minus sign */
int iNumChars = pWork.length();
boolean isNegative = false;
if ((iNumChars > 0)
&& (pWork.charAt(0) == myMinus)) {
/* Delete it and note the presence */
pWork.deleteCharAt(0);
iNumChars--;
isNegative = true;
}
/* Look for currency symbol as leading non-digits and non-whitespace */
int iNumSymbols = 0;
while (iNumSymbols < iNumChars) {
final char c = pWork.charAt(iNumSymbols);
if (Character.isDigit(c)
|| (c == OceanusDecimalFormatter.CHAR_MINUS)
|| Character.isWhitespace(c)) {
break;
}
iNumSymbols++;
}
/* If we have a symbol */
if (iNumSymbols > 0) {
/* Extract Symbol from buffer */
final String mySymbol = pWork.substring(0, iNumSymbols);
pWork.delete(0, iNumSymbols);
/* Parse the currency symbol */
myCurrency = theLocale.parseCurrencySymbol(mySymbol);
}
/* If we were negative */
if (isNegative) {
/* Reinsert the minus sign */
pWork.insert(0, myMinus);
}
/* Return the currency */
return myCurrency;
}
/**
* Parse a long value.
* @param pValue The value to parse.
* @param pLocale the Decimal locale
* @return the long value
* @throws IllegalArgumentException on invalid decimal
*/
protected static long parseLongValue(final String pValue,
final OceanusDecimalLocale pLocale) {
/* Handle null value */
if (pValue == null) {
throw new IllegalArgumentException();
}
/* Create a working copy */
final StringBuilder myWork = new StringBuilder(pValue.trim());
/* If the value is negative, strip the leading minus sign */
final boolean isNegative = (myWork.length() > 0)
&& (myWork.charAt(0) == pLocale.getMinusSign());
if (isNegative) {
myWork.deleteCharAt(0);
}
/* Remove any grouping characters from the value */
final String myGrouping = pLocale.getGrouping();
int myPos;
for (;;) {
myPos = myWork.indexOf(myGrouping);
if (myPos == -1) {
break;
}
myWork.deleteCharAt(myPos);
}
/* Trim leading and trailing blanks again */
trimBuffer(myWork);
/* Parse the long value */
long myValue;
try {
myValue = Long.parseLong(myWork.toString());
} catch (NumberFormatException e) {
throw new IllegalArgumentException(ERROR_PARSE
+ pValue, e);
}
/* If the value is negative, negate the number */
if (isNegative) {
myValue = -myValue;
}
/* return the result */
return myValue;
}
/**
* Obtain a new zero money value for the default currency.
* @return the new money
*/
public OceanusMoney zeroMoney() {
return new OceanusMoney(theLocale.getDefaultCurrency());
}
/**
* Obtain a new zero money value for the currency.
* @param pCurrency the currency
* @return the new money
*/
public OceanusMoney zeroMoney(final Currency pCurrency) {
return new OceanusMoney(pCurrency);
}
/**
* Parse Money value.
* @param pValue the string value to parse.
* @return the parsed money
* @throws IllegalArgumentException on invalid money value
*/
public OceanusMoney parseMoneyValue(final String pValue) {
return parseMoneyValue(pValue, null);
}
/**
* Parse Money value.
* @param pValue the string value to parse.
* @param pDeemedCurrency the assumed currency if no currency identifier
* @return the parsed money
* @throws IllegalArgumentException on invalid money value
*/
public OceanusMoney parseMoneyValue(final String pValue,
final Currency pDeemedCurrency) {
/* Handle null value */
if (pValue == null) {
return null;
}
/* Create a working trimmed copy */
final StringBuilder myWork = new StringBuilder(pValue.trim());
/* Determine currency */
final Currency myCurrency = parseCurrency(myWork, pDeemedCurrency == null
? getDefaultCurrency()
: pDeemedCurrency);
final char myMinus = theLocale.getMinusSign();
/* If we have a leading minus sign */
if ((myWork.length() > 0)
&& (myWork.charAt(0) == myMinus)) {
/* Ensure there is no whitespace between minus sign and number */
myWork.deleteCharAt(0);
trimBuffer(myWork);
myWork.insert(0, myMinus);
}
/* Create the new Money object */
final OceanusMoney myMoney = new OceanusMoney(myCurrency);
/* Parse the remaining string */
parseDecimalValue(myWork.toString(), theLocale, true, myMoney);
/* Correct the scale */
adjustDecimals(myMoney, myCurrency.getDefaultFractionDigits());
/* return the parsed money object */
return myMoney;
}
/**
* Obtain a new zero price value for the default currency.
* @return the new price
*/
public OceanusPrice zeroPrice() {
return new OceanusPrice(theLocale.getDefaultCurrency());
}
/**
* Obtain a new zero price value for the currency.
* @param pCurrency the currency
* @return the new price
*/
public OceanusPrice zeroPrice(final Currency pCurrency) {
return new OceanusPrice(pCurrency);
}
/**
* Parse Price value.
* @param pValue the string value to parse.
* @return the parsed price
* @throws IllegalArgumentException on invalid price value
*/
public OceanusPrice parsePriceValue(final String pValue) {
return parsePriceValue(pValue, null);
}
/**
* Parse Price value.
* @param pValue the string value to parse.
* @param pDeemedCurrency the assumed currency if no currency identifier
* @return the parsed price
* @throws IllegalArgumentException on invalid price value
*/
public OceanusPrice parsePriceValue(final String pValue,
final Currency pDeemedCurrency) {
/* Handle null value */
if (pValue == null) {
return null;
}
/* Create a working trimmed copy */
final StringBuilder myWork = new StringBuilder(pValue.trim());
/* Look for explicit currency */
final Currency myCurrency = parseCurrency(myWork, pDeemedCurrency == null
? getDefaultCurrency()
: pDeemedCurrency);
final char myMinus = theLocale.getMinusSign();
/* If we have a leading minus sign */
if (myWork.charAt(0) == myMinus) {
/* Ensure there is no whitespace between minus sign and number */
myWork.deleteCharAt(0);
trimBuffer(myWork);
myWork.insert(0, myMinus);
}
/* Create the new Price object */
final OceanusPrice myPrice = new OceanusPrice(myCurrency);
/* Parse the remaining string */
parseDecimalValue(myWork.toString(), theLocale, true, myPrice);
/* Correct the scale */
adjustDecimals(myPrice, myCurrency.getDefaultFractionDigits()
+ OceanusPrice.XTRA_DECIMALS);
/* return the parsed price object */
return myPrice;
}
/**
* Parse Rate value.
* @param pValue the string value to parse.
* @return the parsed rate
* @throws IllegalArgumentException on invalid rate value
*/
public OceanusRate parseRateValue(final String pValue) {
/* Handle null value */
if (pValue == null) {
return null;
}
/* Create a working trimmed copy */
final StringBuilder myWork = new StringBuilder(pValue.trim());
int myXtraDecimals = 0;
/* If there is a trailing perCent, remove any percent sign from the end of the string */
final int myLast = myWork.length() - 1;
if (myWork.charAt(myLast) == theLocale.getPerCent()) {
myWork.deleteCharAt(myLast);
myXtraDecimals = ADJUST_PERCENT;
/*
* If there is a trailing perMille, remove any percent sign from the end of the string
*/
} else if (myWork.charAt(myLast) == theLocale.getPerMille()) {
myWork.deleteCharAt(myLast);
myXtraDecimals = ADJUST_PERMILLE;
}
/* Create the new Rate object */
final OceanusRate myRate = new OceanusRate();
/* Parse the remaining string */
parseDecimalValue(myWork.toString(), theLocale, false, myRate);
/* If we have extra Decimals to add */
if (myXtraDecimals > 0) {
/* Adjust the value appropriately */
myRate.recordScale(myXtraDecimals
+ myRate.scale());
}
/* Correct the scale */
adjustDecimals(myRate, OceanusRate.NUM_DECIMALS);
/* return the parsed rate object */
return myRate;
}
/**
* Parse Units value.
* @param pValue the string value to parse.
* @return the parsed units
* @throws IllegalArgumentException on invalid units value
*/
public OceanusUnits parseUnitsValue(final String pValue) {
/* Handle null value */
if (pValue == null) {
return null;
}
/* Create the new Units object */
final OceanusUnits myUnits = new OceanusUnits();
/* Parse the remaining string */
parseDecimalValue(pValue.trim(), theLocale, false, myUnits);
/* Correct the scale */
adjustDecimals(myUnits, OceanusUnits.NUM_DECIMALS);
/* return the parsed units object */
return myUnits;
}
/**
* Parse Ratio value.
* @param pValue the string value to parse.
* @return the parsed ratio
* @throws IllegalArgumentException on invalid ratio value
*/
public OceanusRatio parseRatioValue(final String pValue) {
/* Handle null value */
if (pValue == null) {
return null;
}
/* Create the new Ratio object */
final OceanusRatio myRatio = new OceanusRatio();
/* Parse the remaining string */
parseDecimalValue(pValue.trim(), theLocale, false, myRatio);
/* Correct the scale */
adjustDecimals(myRatio, OceanusRatio.NUM_DECIMALS);
/* return the parsed ratio object */
return myRatio;
}
/**
* Parse Decimal value.
* @param pValue the string value to parse.
* @param pScale the scale of the resulting decimal
* @return the parsed decimal
* @throws IllegalArgumentException on invalid decimal value
*/
public OceanusDecimal parseDecimalValue(final String pValue,
final int pScale) {
/* Handle null value */
if (pValue == null) {
return null;
}
/* Create the new Decimal object */
final OceanusDecimal myDecimal = new OceanusDecimal();
/* Parse the remaining string */
parseDecimalValue(pValue.trim(), theLocale, false, myDecimal);
adjustDecimals(myDecimal, pScale);
/* return the parsed decimal object */
return myDecimal;
}
/**
* Parse Long value.
* @param pValue the string value to parse.
* @return the parsed value
* @throws IllegalArgumentException on invalid value
*/
public Long parseLongValue(final String pValue) {
/* Handle null value */
if (pValue == null) {
return null;
}
/* Parse the value */
final long myValue = parseLongValue(pValue, theLocale);
return Long.valueOf(myValue);
}
/**
* Parse Integer value.
* @param pValue the string value to parse.
* @return the parsed value
* @throws IllegalArgumentException on invalid value
*/
public Integer parseIntegerValue(final String pValue) {
/* Handle null value */
if (pValue == null) {
return null;
}
/* Parse the value */
final long myValue = parseLongValue(pValue, theLocale);
/* Check bounds */
if ((myValue > Integer.MAX_VALUE) || (myValue < Integer.MIN_VALUE)) {
throw new IllegalArgumentException(ERROR_BOUNDS
+ pValue);
}
/* Return value */
return Integer.valueOf((int) myValue);
}
/**
* Parse Short value.
* @param pValue the string value to parse.
* @return the parsed value
* @throws IllegalArgumentException on invalid value
*/
public Short parseShortValue(final String pValue) {
/* Handle null value */
if (pValue == null) {
return null;
}
/* Parse the value */
final long myValue = parseLongValue(pValue, theLocale);
/* Check bounds */
if ((myValue > Short.MAX_VALUE) || (myValue < Short.MIN_VALUE)) {
throw new IllegalArgumentException(ERROR_BOUNDS
+ pValue);
}
/* Return value */
return (short) myValue;
}
/**
* Trim parsing buffer.
* @param pBuffer the buffer to trim
*/
private static void trimBuffer(final StringBuilder pBuffer) {
/* Remove leading blanks */
while (pBuffer.length() > 0
&& Character.isWhitespace(pBuffer.charAt(0))) {
pBuffer.deleteCharAt(0);
}
/* Remove trailing blanks */
int myLen = pBuffer.length();
while (myLen-- > 0) {
if (!Character.isWhitespace(pBuffer.charAt(myLen))) {
break;
}
pBuffer.deleteCharAt(myLen);
}
}
/**
* create Money from double.
* @param pValue the double value.
* @return the parsed money
* @throws IllegalArgumentException on invalid money value
*/
public OceanusMoney createMoneyFromDouble(final Double pValue) {
/* Handle null value */
if (pValue == null) {
return null;
}
/* Use default currency */
final Currency myCurrency = theLocale.getDefaultCurrency();
return createMoneyFromDouble(pValue, myCurrency.getCurrencyCode());
}
/**
* create Money from double.
* @param pValue the double value.
* @param pCurrCode the currency code
* @return the parsed money
* @throws IllegalArgumentException on invalid money value
*/
public OceanusMoney createMoneyFromDouble(final Double pValue,
final String pCurrCode) {
/* Handle null value */
if (pValue == null) {
return null;
}
/* Determine currency */
final Currency myCurrency = Currency.getInstance(pCurrCode);
/* Create the new Money object */
final OceanusMoney myMoney = new OceanusMoney(myCurrency);
/* Parse the remaining string */
parseDecimalValue(pValue.toString(), theLocale, true, myMoney);
/* Correct the scale */
adjustDecimals(myMoney, myCurrency.getDefaultFractionDigits());
/* return the parsed money object */
return myMoney;
}
/**
* create Price from double.
* @param pValue the double value.
* @return the parsed price
* @throws IllegalArgumentException on invalid price value
*/
public OceanusPrice createPriceFromDouble(final Double pValue) {
/* Handle null value */
if (pValue == null) {
return null;
}
/* Use default currency */
final Currency myCurrency = theLocale.getDefaultCurrency();
return createPriceFromDouble(pValue, myCurrency.getCurrencyCode());
}
/**
* create Price from double.
* @param pValue the double value.
* @param pCurrCode the currency code
* @return the parsed price
* @throws IllegalArgumentException on invalid price value
*/
public OceanusPrice createPriceFromDouble(final Double pValue,
final String pCurrCode) {
/* Handle null value */
if (pValue == null) {
return null;
}
/* Determine currency */
final Currency myCurrency = Currency.getInstance(pCurrCode);
/* Create the new Price object */
final OceanusPrice myPrice = new OceanusPrice(myCurrency);
/* Parse the remaining string */
parseDecimalValue(pValue.toString(), theLocale, false, myPrice);
/* Correct the scale */
adjustDecimals(myPrice, myCurrency.getDefaultFractionDigits()
+ OceanusPrice.XTRA_DECIMALS);
/* return the parsed price object */
return myPrice;
}
/**
* create Rate from double.
* @param pValue the double value.
* @return the parsed rate
* @throws IllegalArgumentException on invalid rate value
*/
public OceanusRate createRateFromDouble(final Double pValue) {
/* Handle null value */
if (pValue == null) {
return null;
}
/* Create the new Rate object */
final OceanusRate myRate = new OceanusRate();
/* Parse the remaining string */
parseDecimalValue(pValue.toString(), theLocale, false, myRate);
/* Correct the scale */
adjustDecimals(myRate, OceanusRate.NUM_DECIMALS);
/* return the parsed rate object */
return myRate;
}
/**
* create Units from double.
* @param pValue the double value.
* @return the parsed units
* @throws IllegalArgumentException on invalid units value
*/
public OceanusUnits createUnitsFromDouble(final Double pValue) {
/* Handle null value */
if (pValue == null) {
return null;
}
/* Create the new Units object */
final OceanusUnits myUnits = new OceanusUnits();
/* Parse the remaining string */
parseDecimalValue(pValue.toString(), theLocale, false, myUnits);
/* Correct the scale */
adjustDecimals(myUnits, OceanusUnits.NUM_DECIMALS);
/* return the parsed units object */
return myUnits;
}
/**
* create Ratio from double.
* @param pValue the double value.
* @return the parsed ratio
* @throws IllegalArgumentException on invalid ratio value
*/
public OceanusRatio createRatioFromDouble(final Double pValue) {
/* Handle null value */
if (pValue == null) {
return null;
}
/* Create the new Ratio object */
final OceanusRatio myRatio = new OceanusRatio();
/* Parse the remaining string */
parseDecimalValue(pValue.toString(), theLocale, false, myRatio);
/* Correct the scale */
adjustDecimals(myRatio, OceanusRatio.NUM_DECIMALS);
/* return the parsed ratio object */
return myRatio;
}
}