Better read/write of imprecise fraction

This commit is contained in:
DBotThePony 2022-01-26 14:17:09 +07:00
parent 17af248426
commit 1415c34206
Signed by: DBot
GPG Key ID: DCC23B5715498507
3 changed files with 69 additions and 55 deletions

View File

@ -12,57 +12,60 @@ import kotlin.math.absoluteValue
private fun isZero(value: BigInteger) = value == BigInteger.ZERO
private val LONG_BUFF = ByteBuffer.allocate(8)
private fun byteToInt(value: Byte): Int {
if (value < 0) {
return 256 + value
private fun unsignedInt(value: Byte): Int {
return value.toInt() and 0xFF
}
return value.toInt()
private fun usignedLong(value: Byte): Long {
return value.toLong() and 0xFFL
}
private fun longToBytes(value: Long): ByteArray {
LONG_BUFF.position(0)
LONG_BUFF.putLong(value)
return LONG_BUFF.array().copyOf()
private fun longToBytesBE(value: Long): ByteArray {
return byteArrayOf(
(value ushr 56).toByte(),
(value ushr 48).toByte(),
(value ushr 40).toByte(),
(value ushr 32).toByte(),
(value ushr 24).toByte(),
(value ushr 16).toByte(),
(value ushr 8).toByte(),
(value).toByte(),
)
}
private fun bytesToLong(value: ByteArray, from: Int = 0): Long {
val arr = LONG_BUFF.array()
arr[0] = value[from]
arr[1] = value[from + 1]
arr[2] = value[from + 2]
arr[3] = value[from + 3]
arr[4] = value[from + 4]
arr[5] = value[from + 5]
arr[6] = value[from + 6]
arr[7] = value[from + 7]
LONG_BUFF.position(0)
return LONG_BUFF.long
private fun bytesToLongBE(value: ByteArray, from: Int = 0): Long {
return (
(usignedLong(value[from + 7])) or
(usignedLong(value[from + 6]) shl 8) or
(usignedLong(value[from + 5]) shl 16) or
(usignedLong(value[from + 4]) shl 24) or
(usignedLong(value[from + 3]) shl 32) or
(usignedLong(value[from + 2]) shl 40) or
(usignedLong(value[from + 1]) shl 48) or
(usignedLong(value[from]) shl 56)
)
}
private fun bytesToLong(
value0: Byte,
value1: Byte,
value2: Byte,
value3: Byte,
value4: Byte,
value5: Byte,
value6: Byte,
private fun bytesToLongBE(
value7: Byte,
value6: Byte,
value5: Byte,
value4: Byte,
value3: Byte,
value2: Byte,
value1: Byte,
value0: Byte,
): Long {
val arr = LONG_BUFF.array()
arr[0] = value0
arr[1] = value1
arr[2] = value2
arr[3] = value3
arr[4] = value4
arr[5] = value5
arr[6] = value6
arr[7] = value7
LONG_BUFF.position(0)
return LONG_BUFF.long
return (
(usignedLong(value0)) or
(usignedLong(value1) shl 8) or
(usignedLong(value2) shl 16) or
(usignedLong(value3) shl 24) or
(usignedLong(value4) shl 32) or
(usignedLong(value5) shl 40) or
(usignedLong(value6) shl 48) or
(usignedLong(value7) shl 56)
)
}
const val EPSILON = 0.0000001
@ -330,7 +333,7 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do
fun toByteArray(): ByteArray {
val whole = whole.toByteArray()
return byteArrayOf(whole.size.toByte(), *whole, *longToBytes(decimal.toBits()))
return byteArrayOf(whole.size.toByte(), *whole, *longToBytesBE(decimal.toBits()))
}
fun serializeNBT(): Tag {
@ -388,7 +391,10 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do
}
fun write(buff: FriendlyByteBuf) {
buff.writeBytes(toByteArray())
val whole = whole.toByteArray()
buff.writeByte(whole.size)
buff.writeBytes(whole)
buff.writeBytes(longToBytesBE(decimal.toBits()))
}
fun toFloat(): Float {
@ -446,9 +452,9 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do
@JvmStatic
fun fromByteArray(input: ByteArray): ImpreciseFraction {
val size = byteToInt(input[0])
val size = unsignedInt(input[0])
val slice = input.copyOfRange(1, 1 + size)
val bits = bytesToLong(input, 1 + size)
val bits = bytesToLongBE(input, 1 + size)
return ImpreciseFraction(BigInteger(slice), Double.fromBits(bits))
}
@ -465,13 +471,13 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do
@JvmStatic
fun read(buff: FriendlyByteBuf): ImpreciseFraction {
val len = byteToInt(buff.readByte())
val len = unsignedInt(buff.readByte())
val slice = ByteArray(len)
for (i in 0 until len)
slice[i] = buff.readByte()
val bits = bytesToLong(buff.readByte(), buff.readByte(), buff.readByte(), buff.readByte(), buff.readByte(), buff.readByte(), buff.readByte(), buff.readByte())
val bits = bytesToLongBE(buff.readByte(), buff.readByte(), buff.readByte(), buff.readByte(), buff.readByte(), buff.readByte(), buff.readByte(), buff.readByte())
return ImpreciseFraction(BigInteger(slice), Double.fromBits(bits))
}
}

View File

@ -133,12 +133,12 @@ class ItemBattery : Item {
p_41423_.add(INFINITE_STORAGE)
p_41423_.add(throughputText)
} else {
stack.getCapability(MatteryCapability.ENERGY).ifPresent { cap: IMatteryEnergyStorage ->
stack.getCapability(MatteryCapability.ENERGY).ifPresent {
p_41423_.add(
TranslatableComponent(
"otm.item.power.normal.storage",
FormattingHelper.formatPower(cap.batteryLevel),
FormattingHelper.formatPower(cap.maxBatteryLevel)
FormattingHelper.formatPower(it.batteryLevel),
FormattingHelper.formatPower(it.maxBatteryLevel)
).withStyle(ChatFormatting.GRAY)
)
}

View File

@ -36,8 +36,16 @@ object ImpreciseFractionTests {
@Test
@DisplayName("ImpreciseFraction store/load")
fun storeLoad() {
run {
val f = ImpreciseFraction(4, 0.28)
val loaded = ImpreciseFraction.fromByteArray(f.toByteArray())
check(f == loaded) { "$f != $loaded" }
}
run {
val f = ImpreciseFraction(32748293658335L, 0.3472302174)
val loaded = ImpreciseFraction.fromByteArray(f.toByteArray())
check(f == loaded) { "$f != $loaded" }
}
}
}