划分值给我一个小的不准确性?

时间:2013-12-02 21:30:26

标签: java

所以我一直在构建一些单位转换工具,这里有一段代码,其中包含我的问题:

public static void main(String args[]) {
    double value = 100;
    System.out.println("Value in millimeters: " + value);
    value = ConversionTools.toFeet(ConversionTools.MILLIMETER, value);
    System.out.println("Value in feet: " + value);
    System.exit(0);
}
class ConversionTools {
// Start constants
public static final int MILLIMETER      = 0;
public static final int CENTIMETER      = 1;
public static final int DECIMETER       = 2;
public static final int METER           = 3;
public static final int DECAMETER       = 4;
public static final int HECTOMETER      = 5;
public static final int KILOMETER       = 6;
public static final int INCH            = 7;
public static final int FOOT            = 8;
public static final int YARD            = 9;
public static final int MILE            = 10;

private static final double KILOMETERS_TO_HECTOMETERS = 10;
private static final double HECTOMETERS_TO_DECAMETERS = 10;
private static final double DECAMETERS_TO_METERS = 10;
private static final double METERS_TO_DECIMETERS = 10;
private static final double DECIMETERS_TO_CENTIMETERS = 10;
private static final double CENTIMETERS_TO_MILLIMETERS = 10;

private static final double MILES_TO_YARDS = 1760;
private static final double YARDS_TO_FEET = 3;
private static final double FEET_TO_INCHES = 12;

private static final double METERS_TO_FEET = 3.28084;
// End constants

/**
 * Converts a distance to meters
 * @param type the type of distance
 * @param value the value of the distance
 * @return  returns the converted distance, or Double.MIN_VALUE
 * if the type is not recognized
 */
public static double toMeters(int type, double value) {
    if (type == MILLIMETER)         return toMeters(CENTIMETER, (double) value / CENTIMETERS_TO_MILLIMETERS);
    else if (type == CENTIMETER)    return toMeters(DECIMETER, (double) value / DECIMETERS_TO_CENTIMETERS);
    else if (type == DECIMETER)     return toMeters(METER, (double) value / METERS_TO_DECIMETERS);
    else if (type == METER)         return value;
    else if (type == DECAMETER)     return toMeters(METER, (double) value * DECAMETERS_TO_METERS);
    else if (type == HECTOMETER)    return toMeters(DECAMETER, (double) value * HECTOMETERS_TO_DECAMETERS);
    else if (type == KILOMETER)     return toMeters(HECTOMETER, (double) value * KILOMETERS_TO_HECTOMETERS);
    else if (type == INCH)          return toMeters(FOOT, toFeet(INCH, value));
    else if (type == FOOT)          return toMeters(METER, (double) value / METERS_TO_FEET);
    else if (type == YARD)          return toMeters(FOOT, toFeet(YARD, value));
    else if (type == MILE)          return toMeters(FOOT, toFeet(MILE, value));
    else                            return Double.MIN_VALUE;
}
/**
 * Converts a distance to feet
 * @param type the type of distance
 * @param value the value of the distance
 * @return returns the converted distance, or Double.MIN_VALUE
 * if the type is not recognized
 */
public static double toFeet(int type, double value) {
    if (type == INCH)               return toFeet(FOOT, (double) value / FEET_TO_INCHES);
    else if (type == FOOT)          return value;
    else if (type == YARD)          return toFeet(FOOT, (double) value * YARDS_TO_FEET);
    else if (type == MILE)          return toFeet(YARD, (double) value * MILES_TO_YARDS);
    else if (type == MILLIMETER)    return toFeet(METER, toMeters(MILLIMETER, value));
    else if (type == CENTIMETER)    return toFeet(METER, toMeters(CENTIMETER, value));
    else if (type == DECIMETER)     return toFeet(METER, toMeters(DECIMETER, value));
    else if (type == METER)         return toFeet(FOOT, (double) value * METERS_TO_FEET);
    else if (type == DECAMETER)     return toFeet(METER, toMeters(DECAMETER, value));
    else if (type == HECTOMETER)    return toFeet(METER, toMeters(HECTOMETER, value));
    else if (type == KILOMETER)     return toFeet(METER, toMeters(KILOMETER, value));
    else                            return Double.MIN_VALUE;
}

当我运行此代码时,我最终获得此输出:

Value in millimeters: 100.0
Value in feet: 0.32808400000000004

有谁知道为什么我会得到额外的0.4E-16?

另外,对于那些对距离单位的常数有问题的人,我知道我可以使用枚举器,但为了简单起见我现在使用整数。

2 个答案:

答案 0 :(得分:4)

因为Java实现了浮点数的IEEE标准。使用这些数字的操作通常不是100%精确。

这是一篇非常古老的Java文章,它可以为您提供更多详细信息。

http://www.javaworld.com/jw-10-1996/jw-10-hood.html

答案 1 :(得分:2)

这取决于数据类型的精确度。请参阅此链接以获取大量解释:

http://blog.stata.com/2012/04/02/the-penultimate-guide-to-precision/