在我的应用中,我将数字作为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"));
    }
}

08-04 05:05