在我的应用中,我将数字作为BigDecimal处理,并将其存储为NUMBER(15,5)。现在,我需要在Java上正确检查BigDecimal值是否适合该列,以便我可以生成适当的错误消息,而无需执行SQL,捕获异常并验证供应商错误代码。我的数据库是Oracle 10.3,此类错误导致error 1438。
经过一番谷歌搜索后,我没有找到这样的代码,所以我想出了自己的代码。但是我对此代码确实不满意...简单,但同时又足以怀疑其正确性。我用许多值,随机值和边界对其进行了测试,它似乎可以正常工作。但是由于我对数字真的很不好,所以我想要一些更健壮和经过测试的代码。
//no constants for easier reading
public boolean testBigDecimal(BigDecimal value) {
if (value.scale() > 5)
return false;
else if (value.precision() - value.scale() > 15 - 5)
return false;
else
return true;
}
编辑:最近的测试没有超出范围的数字的异常(exception),只是默默地四舍五入,我不确定不是和我做这些第一次测试之间有什么区别。由于应用程序是财务的,因此这种舍入是 Not Acceptable ,并且任何舍入/截断都必须是显式的(通过BigDecimal方法)。除了异常(exception),该测试方法还必须确保该数字对于期望的精度而言不会太大,即使使用非有效数字也是如此。对不起,后期澄清。
谢谢你的时间。
我仍然对这个问题感到好奇。我的代码仍在运行,并且没有某种“证明”正确性或失败的情况,也没有用于这种测试的标准代码。
所以,我为此悬赏,希望得到其中的任何一个。
最佳答案
以下正则表达式也可以解决问题:
public class Big {
private static final Pattern p = Pattern.compile("[0-9]{0,10}(\\.[0-9]{0,5}){0,1}");
public static void main(String[] args) {
BigDecimal b = new BigDecimal("123123.12321");
Matcher m = p.matcher(b.toString());
System.out.println(b.toString() + " is valid = " + m.matches());
}
}
这可能是测试代码的另一种方式,也可能是代码。正则表达式需要0到10位之间的数字,还可以选择后面跟小数点和0到5位以上的数字。我不知道是否需要一个标志。将诸如
[+-]{0,1}
之类的内容添加到最前面即可。也许这是一个更好的类,并且是带有部分测试的测试类。
public class Big {
private static final Pattern p = Pattern.compile("[0-9]{0,10}(\\.[0-9]{0,5}){0,1}");
public static boolean isValid(String s) {
BigDecimal b = new BigDecimal(s);
Matcher m = p.matcher(b.toPlainString());
return m.matches();
}
}
package thop;
import junit.framework.TestCase;
/**
* Created by IntelliJ IDEA.
* User: tonyennis
* Date: Sep 22, 2010
* Time: 6:01:15 PM
* To change this template use File | Settings | File Templates.
*/
public class BigTest extends TestCase {
public void testZero1() {
assertTrue(Big.isValid("0"));
}
public void testZero2() {
assertTrue(Big.isValid("0."));
}
public void testZero3() {
assertTrue(Big.isValid("0.0"));
}
public void testZero4() {
assertTrue(Big.isValid(".0"));
}
public void testTooMuchLeftSide() {
assertFalse(Big.isValid("12345678901.0"));
}
public void testMaxLeftSide() {
assertTrue(Big.isValid("1234567890.0"));
}
public void testMaxLeftSide2() {
assertTrue(Big.isValid("000001234567890.0"));
}
public void testTooMuchScale() {
assertFalse(Big.isValid("0.123456"));
}
public void testScientificNotation1() {
assertTrue(Big.isValid("123.45e-1"));
}
public void testScientificNotation2() {
assertTrue(Big.isValid("12e4"));
}
}