Java 根据自定义条件将浮点数转换为字节
Java convert float to byte on custom terms
我想write/read 0-15 from/to 数百万个数字一个文件。精度不是问题,只要读取值在写入值的+-0.1以内,一切都很好。
以前的想法
我的第一个不成熟的想法是像这样将浮点数转换为字符串并将它们写成 space 分隔:
String.format("%.1f%s", float)
这当然是非常低效的,因为它为每个浮点数使用 4-5 个字节。
然后我想到了只写每个浮点数的字节,这样会更快但不足以减小大小。
ByteBuffer.allocate(4).putFloat(float).array()
当前问题
我目前的想法是将浮点数减少到一个字节。查看我需要的范围和精度,我会分配前 4 位来表示浮点数之前的小数,最后 4 位到尾部。
但是我怎样才能快速获得这些位,因为它必须完成数百万次?
因为你的尾巴是个位数,它可以是隐式的 - 即 14.3 转换为 143。要转换回来,只需 143 / 10
得到整个部分,143 % 10
得到分数。这是一个实现的样子。
public class Test {
public static void main(String[] args) {
float floatValue = 14.1f;
Test test = new Test();
byte b = test.toByteStorage(floatValue);
System.out.println(test.fromByteStorage(b));
}
byte toByteStorage(float f) {
return (byte) (f * 10);
}
String fromByteStorage(byte b) {
int intValue = Byte.toUnsignedInt(b);
return intValue / 10 + "." + intValue % 10;
}
}
你可能会使用这样的东西:
// conversion factor to map 15.0 to 0xF0
float m = (float) (0xF0 / 15.0);
for (float x = 0.0f; x <= 15.0f; x += 0.25f) {
// obtain byte corresponding to float
byte b = (byte) (m * x);
// recover float from byte to check conversion
// mask off sign bit to convert signed to unsigned byte
float r = (b & 0x0FF) / m;
// what is the difference between original float and
// recovered float?
float error = Math.abs(x - r);
// show all values for testing
String s = " b=0x" + Integer.toHexString(b & 0x0FF) +
" r=" + Float.toString(r) +
" err=" + Float.toString(error);
System.out.println(s);
}
我想write/read 0-15 from/to 数百万个数字一个文件。精度不是问题,只要读取值在写入值的+-0.1以内,一切都很好。
以前的想法
我的第一个不成熟的想法是像这样将浮点数转换为字符串并将它们写成 space 分隔:
String.format("%.1f%s", float)
这当然是非常低效的,因为它为每个浮点数使用 4-5 个字节。
然后我想到了只写每个浮点数的字节,这样会更快但不足以减小大小。
ByteBuffer.allocate(4).putFloat(float).array()
当前问题
我目前的想法是将浮点数减少到一个字节。查看我需要的范围和精度,我会分配前 4 位来表示浮点数之前的小数,最后 4 位到尾部。
但是我怎样才能快速获得这些位,因为它必须完成数百万次?
因为你的尾巴是个位数,它可以是隐式的 - 即 14.3 转换为 143。要转换回来,只需 143 / 10
得到整个部分,143 % 10
得到分数。这是一个实现的样子。
public class Test {
public static void main(String[] args) {
float floatValue = 14.1f;
Test test = new Test();
byte b = test.toByteStorage(floatValue);
System.out.println(test.fromByteStorage(b));
}
byte toByteStorage(float f) {
return (byte) (f * 10);
}
String fromByteStorage(byte b) {
int intValue = Byte.toUnsignedInt(b);
return intValue / 10 + "." + intValue % 10;
}
}
你可能会使用这样的东西:
// conversion factor to map 15.0 to 0xF0
float m = (float) (0xF0 / 15.0);
for (float x = 0.0f; x <= 15.0f; x += 0.25f) {
// obtain byte corresponding to float
byte b = (byte) (m * x);
// recover float from byte to check conversion
// mask off sign bit to convert signed to unsigned byte
float r = (b & 0x0FF) / m;
// what is the difference between original float and
// recovered float?
float error = Math.abs(x - r);
// show all values for testing
String s = " b=0x" + Integer.toHexString(b & 0x0FF) +
" r=" + Float.toString(r) +
" err=" + Float.toString(error);
System.out.println(s);
}