由于 float 是以 2 为基数的数字系统,因此无法直接表示 0.24F
,因为如果没有,则无法在十进制系统中表示 1/3
recurring decimal period即 1/3=0.3333...
或 0.(3)
。
因此 float 0.24F
当打印回十进制表示形式时显示为 0.23
由于四舍五入而发生变化:
println(0.24F) => 0.23999999463558197021484375
而0.25F
可以直接显示:
println(0.25F) => 0.25
但是我怎样才能确定一个数字是完全可表示的呢?
isExactFloat(0.25F) ==> true
isExactFloat(0.24F) ==> false
也许 Java API 已经有一些功能可以做到这一点?
UPD 下面是一段代码,显示 [-4, 4] 范围内的 float 及其内部表示:
public class FloatDestructure {
public static void main(String[] args) {
BigDecimal dec = BigDecimal.valueOf(-4000L, 3);
BigDecimal incr = BigDecimal.valueOf(1L, 3);
for (int i = 0; i <= 8000; i++) {
double dbl = dec.doubleValue();
floatDestuct(dbl, dec);
dec = dec.add(incr);
}
}
static boolean isExactFloat(double d) { return d == (float) d; }
static void floatDestuct(double val, BigDecimal dec) {
float value = (float) val;
int bits = Float.floatToIntBits(value);
int sign = bits >>> 31;
int exp = (bits >>> 23 & ((1 << 8) - 1)) - ((1 << 7) - 1);
int mantissa = bits & ((1 << 23) - 1);
float backToFloat = Float.intBitsToFloat((sign << 31) | (exp + ((1 << 7) - 1)) << 23 | mantissa);
boolean exactFloat = isExactFloat(val);
boolean exactFloatStr = Double.toString(value).length() <= 7;
System.out.println(dec.toString() + " " + (double) val + " " + (double) value + " sign: " + sign + " exp: " + exp + " mantissa: " + mantissa + " " + Integer.toBinaryString(mantissa) + " " + (double) backToFloat + " " + exactFloat + " " + exactFloatStr);
}
}
当尾数为零时, float 绝对准确。但在其他情况下,例如 -0.375
或 -1.625
就不是那么清楚了。
最佳答案
一般来说,这是不可能的。 一旦将数字转换为 float 或 double ,它就只是数字的近似值。因此,您对 isexactfloat() 的输入将不准确...
如果您有精确版本的 float ,例如字符串格式,那么就可以设计一个函数来告诉您 float 或 double 是否准确表示字符串格式的数字。请参阅下面 Carlos Heurberger 关于如何实现此类功能的评论。
关于java - 如何确定数字是否可以精确表示为 float ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52705419/