Java中最大精度的测试编号
我想测试一个最大感知为3或更少的双人床。在Java中实现这一点的最佳方法是什么Java中最大精度的测试编号,java,precision,Java,Precision,我想测试一个最大感知为3或更少的双人床。在Java中实现这一点的最佳方法是什么 20.44567567 <- Fail 20.444 <- Pass 20.1 <- Pass 20 <- Pass 1不要使用双刀。浮点逻辑充其量是近似的。改用BigDecimal 2我认为BigDecimal已经有了设置精度的方法。如果不是,就乘以1000和trunc。执行该操作,获取一个新编号,并与原始编号进行比较。如果不同,则失败。1不要使用双精度。浮点逻辑充其量是近似的。改用Big
20.44567567 <- Fail
20.444 <- Pass
20.1 <- Pass
20 <- Pass
1不要使用双刀。浮点逻辑充其量是近似的。改用BigDecimal
2我认为BigDecimal已经有了设置精度的方法。如果不是,就乘以1000和trunc。执行该操作,获取一个新编号,并与原始编号进行比较。如果不同,则失败。1不要使用双精度。浮点逻辑充其量是近似的。改用BigDecimal
2我认为BigDecimal已经有了设置精度的方法。如果不是,就乘以1000和trunc。执行该操作,获取一个新编号,并与原始编号进行比较。如果不同,则失败。这通过了您的测试:
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;
}
}
这通过了您的测试:
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;
}
}
您可以使用以下代码:
boolean f (double in){
if (in*1000 > (float)(int)(in*1000))
return false;
return true;
}
您可以使用以下代码:
boolean f (double in){
if (in*1000 > (float)(int)(in*1000))
return false;
return true;
}
该术语有多种可能的解释: 算术精度是小数点前后有效数字的总数。 数字小数部分的位数或小数位数。 特别是在数据库中,精度可以用固定的小数位数(计数中包含的小数位数)来衡量,因此数字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 ) );
}
}
该术语有多种可能的解释: 算术精度是小数点前后有效数字的总数。 数字小数部分的位数或小数位数。 特别是在数据库中,精度可以用固定的小数位数(计数中包含的小数位数)来衡量,因此数字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 ) );
}
}
这个问题没有多大意义。在内部,双值是IEEE-754浮点值。精度的概念仅在转换为字符串表示或BCD时适用,例如使用BigDecimal。此外,20.1不是与20.10000相同的值吗?请使用BigDecimal类型。有非常方便的方法来处理这类任务,比如-obj.precision,obj.scale。我把它解析为一个大十进制而不是一个双精度。为什么有人会否决这个问题,这里有一些很好的反馈。在这个问题中,精度的使用方式与数据库中使用该术语的方式以及算术精度的典型含义不同。示例输出显示测试小数位数而不是精度,因为20.444有3位小数,但有效位数精度为5。如果测试的精度为3,则1230000、123、1.23和0.000123将全部通过,12340000、1234、1.234和0.0001234将全部失败。这个问题没有多大意义。在内部,双值是IEEE-754浮点值。精度的概念仅在转换为字符串表示或BCD时适用,例如使用BigDecimal。此外,20.1不是与20.10000相同的值吗?请使用BigDecimal类型。有非常方便的方法来处理这类任务,比如-obj.precision,obj.scale。我把它解析为一个大十进制而不是一个双精度。为什么有人会否决这个问题,这里有一些很好的反馈。在这个问题中,精度的使用方式与数据库中使用该术语的方式以及算术精度的典型含义不同。示例输出显示测试小数位数而不是精度,因为20.444有3位小数,但有效位数精度为5。如果测试精度为3,则1230000、123、1.23和0.000123将全部通过,12340000、1234、1.234和0.0001234将全部失败。第二点正确,该方法将返回小数点后的位数。我采用了这种方法,它对.scale函数非常有效。@boomz:与使用双精度和/或浮点类型相比,性能问题绝对可以忽略不计。@Lion我不同意你的看法。BigDecimal正在使用字符串,它比double慢。double的性能至少比BigDecimal好2倍。不止这些@boomz:我没有说BigDecimal的性能高于double。我刚才说-性能问题是可以避免的,因为双精度和/或浮点类型的问题相对来说比性能更关键。第二点你是对的,该方法将返回小数点后的位数。我接着说
使用这种方法,它与.scale函数配合得非常好。@boomz:与使用双精度和/或浮点类型相比,性能问题显然可以忽略不计。@Lion我不同意你的看法。BigDecimal正在使用字符串,它比double慢。double的性能至少比BigDecimal好2倍。不止这些@boomz:我没有说BigDecimal的性能高于double。我刚才说-性能问题是可以避免的,因为双精度和/或浮点类型的问题相对来说比性能更为严重。建议使用双精度而不是浮点!在第二行代码中!建议使用double而不是float!在第二行代码中!