90% of ad revenue goes to creators. Go ad-free while supporting creators with Modrinth Plus. Subscribe today!

Flop | floating point operations for Minecraft

This datapack is a library for handling floating-point operations using scoreboards. A new data representation, the 'eroxifloat', is introduced to support this.

What is a floating-point number?

A floating-point number is a way to represent real numbers in binary. It consists of three parts:
  • Sign: whether the number is positive or negative
  • Exponent: determines the magnitude of the number
  • Mantissa: determines the precision to which numbers can be represented

The numerical value of this representation is:

$$(-1)^\text{sign} \times \text{mantissa} \times 2^\text{exponent} $$

The Eroxifloat

An eroxifloat uses 3 scoreboards to store the sign, exponent and mantissa separately. Functions are provided to convert floating-point numbers in NBT storage to eroxifloats and back again. All math operations are performed on this scoreboard representation, but there are also functions provided that perform all the conversions so that you can simply do math on numbers in NBT storage.

The eroxifloat uses 30 bits to represent the mantissa, making it slightly more precise than a float, but less precise than a double. It is worth to note that the division and square root operations only have 15-bit precision. All other operation preserve 30-bit precision.

The sign can take on the values -1 and 1, rather than 0 and 1 as is the case in regular floating point representations.

How to use

Before you can use the pack, you need to run the function flop:api/create_scoreboards to set up the required scoreboard objectives and values. This function is not included in the minecraft:load tag by default, you need to run it yourself.

Currently, the following six operations are available:

  • Addition ($a + b$)
  • Subtraction ($a - b$)
  • Multiplication ($a \times b$)
  • Division ($\frac{a}{b}$)
  • Square ($x^2$)
  • Square root ($\sqrt{x}$)

The easiest way to use this library is to make use of the functions in the flop:api/storage/ folder. These perform operations directly on floating-point numbers in NBT storage. For addition, for example:

data modify storage flop:api operand.a set value 5d

data modify storage flop:api operand.b set value 0.13d

function flop:api/storage/add

data modify <destination> set from storage flop:api output

Operations that take only one input, such as sqrt and square, are used as follows:

data modify storage flop:api input set value 42.0d

function flop:api/storage/sqrt

data modify <destination> set from storage flop:api output

Advanced usage

If you want to calculate complicated formulas, using the operations on storage can cause overhead due to unnecessary conversion between NBT and eroxifloat representations. You can instead perform operations on eroxifloats directly. To create an eroxifloat from a number in NBT storage, use the following function flop:api/storage/read_as_eroxifloat. This will convert the number stored in storage flop:api input into the three scoreboard values input.sign flop, input.exponent flop and input.mantissa flop:

data modify storage flop:api input set value 5d

function flop:api/storage/read_as_eroxifloat

scoreboard players operation <destination 1> = input.sign flop
scoreboard players operation <destination 2> = input.exponent flop
scoreboard players operation <destination 3> = input.mantissa flop

You can then perform the same kinds of calculations as before, but without the overhead of converting to NBT.

scoreboard players operation operand.a.sign flop = <source 1>
scoreboard players operation operand.a.exponent flop = <source 2>
scoreboard players operation operand.a.mantissa flop = <source 3>
scoreboard players operation operand.b.sign flop = <source 4>
scoreboard players operation operand.b.exponent flop = <source 5>
scoreboard players operation operand.b.mantissa flop = <source 6>

function flop:api/eroxifloat/add

scoreboard players operation <destination 1> = output.sign flop
scoreboard players operation <destination 2> = output.exponent flop
scoreboard players operation <destination 3> = output.mantissa flop
scoreboard players operation input.sign flop = <source 1>
scoreboard players operation input.exponent flop = <source 2>
scoreboard players operation input.mantissa flop = <source 3>

function flop:api/eroxifloat/sqrt

scoreboard players operation <destination 1> = output.sign flop
scoreboard players operation <destination 2> = output.exponent flop
scoreboard players operation <destination 3> = output.mantissa flop

And for converting back to NBT, there are two options: writing as a float or as a double. Since the eroxifloat is slightly more precise than a normal float, the latter is reccomended. However, in some cases you may need your number to be a float instead.

scoreboard players operation output.sign flop = <source 1>
scoreboard players operation output.exponent flop = <source 2>
scoreboard players operation output.mantissa flop = <source 3>

function flop:api/eroxifloat/write_to_float
scoreboard players operation output.sign flop = <source 1>
scoreboard players operation output.exponent flop = <source 2>
scoreboard players operation output.mantissa flop = <source 3>

function flop:api/eroxifloat/write_to_double

Final note

Thanks for reading :D
-Eroxen


Project members

Eroxen

Owner

Details

Licensed AGPL-3.0-only
Published a year ago
Updated a year ago