我想测试一个double,最大精度为3或更小。在Java中执行此操作的最佳方法是什么?
20.44567567 <- Fail
20.444 <- Pass
20.1 <- Pass
20 <- Pass
答案 0 :(得分:4)
1)不要使用double
。浮点逻辑最多是近似的。请改用BigDecimal
。
2)我认为BigDecimal
已经有了设定精度的方法。如果没有,只需乘以1000并截断。执行操作,获取新编号,并与原始编号进行比较。如果不同,则失败。
答案 1 :(得分:1)
这通过了你的测试:
package com.sandbox;
import org.junit.Test;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
public class SandboxTest {
@Test
public void testPrecision() {
assertFalse(precisionLessThanOrEqualTo3(20.44567567));
assertTrue(precisionLessThanOrEqualTo3(20.444));
assertTrue(precisionLessThanOrEqualTo3(20.1));
assertTrue(precisionLessThanOrEqualTo3(20));
}
private boolean precisionLessThanOrEqualTo3(double x) {
return String.valueOf(x).replaceAll(".*\\.", "").length() <= 3;
}
}
答案 2 :(得分:1)
您可以使用以下代码:
boolean f (double in){
if (in*1000 > (float)(int)(in*1000))
return false;
return true;
}
答案 3 :(得分:0)
"precision"一词有多种可能的解释:
NUMBER(6,2)
列将存储最多包含6位数字的数字,该数字始终由2位小数组成位和4个整数。在您的示例中,您似乎将测量精度作为最大小数位数。
可以使用以下任何一种方法进行测试:
import java.math.BigDecimal;
import org.junit.Test;
import static org.junit.Assert.*;
public class Precision
{
/**
* Tests to see whether the number has up to the given number of
* decimal places.
*
* @param value The value to test.
* @param scale The maximum number of decimal places.
* @return <code>true</code> if the value has up to the
* expected number of decimal places.
*/
static final boolean hasDecimalPlaces(
final double value,
final int scale
)
{
try
{
new BigDecimal( Double.toString( value ) ).setScale( scale );
return true;
}
catch ( final ArithmeticException ex )
{
return false;
}
}
/**
* Tests to see whether the number has up to the given number of
* significant figures.
*
* @param value The value to test.
* @param precision The maximum number of significant figures to
* test for.
* @return <code>true</code> if the value has up to the
* expected number of significant figures.
*/
static final boolean hasSignificantFigures(
final double value,
final int precision
)
{
try
{
return new BigDecimal( Double.toString( value ) ).stripTrailingZeros().precision() <= precision;
}
catch ( final ArithmeticException ex )
{
return false;
}
}
/**
* Tests to see whether the number has at most the given number of
* decimal places and, when represented at that maximum number of
* decimal places, has up to the given number of digits.
*
* @param value The number to test.
* @param precision The maximum number of digits to test for.
* @param scale The maximum number of decimal places.
* @return <code>true</code> if the value can be represented
* at the given scale and, at that scale, is up to
* the given precision.
*/
static final boolean hasDigitsAtScale(
final double value,
final int precision,
final int scale
)
{
try
{
return new BigDecimal( Double.toString( value ) ).setScale( scale ).precision() <= precision;
}
catch ( final ArithmeticException ex )
{
return false;
}
}
@Test
public void testScale(){
assertTrue( hasDecimalPlaces( 20d, 3 ) );
assertTrue( hasDecimalPlaces( 20.123d, 3 ) );
assertFalse( hasDecimalPlaces( 20.1234d, 3 ) );
}
@Test
public void testPrecision(){
assertTrue( hasSignificantFigures( 20d, 3 ) );
assertTrue( hasSignificantFigures( 120d, 3 ) );
assertTrue( hasSignificantFigures( 1230d, 3 ) );
assertFalse( hasSignificantFigures( 12340d, 3 ) );
assertTrue( hasSignificantFigures( 20.1d, 3 ) );
assertFalse( hasSignificantFigures( 20.12d, 3 ) );
assertTrue( hasSignificantFigures( 0.123d, 3 ) );
assertFalse( hasSignificantFigures( 0.1234d, 3 ) );
assertTrue( hasSignificantFigures( 0.0000999d, 3 ) );
assertFalse( hasSignificantFigures( 0.00009999d, 3 ) );
}
@Test
public void testPrecisionAndScale(){
assertTrue( hasDigitsAtScale( 0d, 3, 0 ) );
assertFalse( hasDigitsAtScale( 0.01d, 3, 0 ) );
assertFalse( hasDigitsAtScale( 0.1d, 3, 0 ) );
assertTrue( hasDigitsAtScale( 1d, 3, 0 ) );
assertTrue( hasDigitsAtScale( 10d, 3, 0 ) );
assertTrue( hasDigitsAtScale( 100d, 3, 0 ) );
assertFalse( hasDigitsAtScale( 1000d, 3, 0 ) );
assertFalse( hasDigitsAtScale( 10000d, 3, 0 ) );
assertTrue( hasDigitsAtScale( 0d, 3, 1 ) );
assertFalse( hasDigitsAtScale( 0.01d, 3, 1 ) );
assertTrue( hasDigitsAtScale( 0.1d, 3, 1 ) );
assertTrue( hasDigitsAtScale( 1d, 3, 1 ) );
assertTrue( hasDigitsAtScale( 10d, 3, 1 ) );
assertFalse( hasDigitsAtScale( 100d, 3, 1 ) );
assertFalse( hasDigitsAtScale( 1000d, 3, 1 ) );
assertFalse( hasDigitsAtScale( 10000d, 3, 1 ) );
assertTrue( hasDigitsAtScale( 0d, 3, -1 ) );
assertFalse( hasDigitsAtScale( 0.01d, 3, -1 ) );
assertFalse( hasDigitsAtScale( 0.1d, 3, -1 ) );
assertFalse( hasDigitsAtScale( 1d, 3, -1 ) );
assertTrue( hasDigitsAtScale( 10d, 3, -1 ) );
assertTrue( hasDigitsAtScale( 100d, 3, -1 ) );
assertTrue( hasDigitsAtScale( 1000d, 3, -1 ) );
assertFalse( hasDigitsAtScale( 10000d, 3, -1 ) );
}
}