-
Bug
-
Resolution: Unresolved
-
None
-
1.15.2, 20w06a, 20w07a, 20w08a, 20w09a, 20w11a, 20w12a, 20w14a, 20w16a, 20w17a, 20w18a, 20w20b, 1.16 Pre-release 5, 1.16.1, 20w27a, 1.16.2 Pre-release 1, 1.16.2, 1.16.3, 1.16.4 Pre-release 1, 1.16.4, 20w45a, 20w46a, 20w48a, 20w49a, 20w51a, 21w03a, 1.16.5, 21w05b, 21w08b, 21w10a, 21w11a, 21w13a, 21w15a, 21w16a, 21w19a, 1.17 Pre-release 1, 1.17, 1.17.1, 21w37a, 1.18.1, 22w03a, 22w05a, 1.18.2 Pre-release 1, 1.18.2, 22w11a, 22w12a, 1.19, 1.19.1, 1.19.2, 1.19.3 Release Candidate 1, 1.19.3 Release Candidate 2, 1.19.3, 23w03a, 23w05a, 23w06a, 1.19.4 Pre-release 3, 1.19.4, 23w12a, 23w13a, 23w14a, 23w16a, 23w17a, 23w18a, 1.20 Pre-release 4, 1.20 Release Candidate 1, 1.20, 1.20.1, 23w31a, 23w32a, 23w33a, 1.20.2, 23w42a, 23w46a, 1.20.4, 24w03a, 24w04a, 24w14a, 1.21, 24w33a, 1.21.1, 1.21.4, 25w04a
-
Confirmed
-
Commands
The bug
It is not possible to create -0.0f/-0.0d in NBT, because 0.0f/0.0d is created instead. This prevents objects in memory containing negative zero from being accurately serialized.
It was possible to create negative zero before 19w38b. However, it became impossible to create them since 19w39a due to NBT caching.
Furthermore, if the Named Binary Tag specification (formerly at http://www.minecraft.net/docs/NBT.txt) is still valid, this behavior would violate the Payload specification for TAG_Float/TAG_Double: A floating point value (32 bits, big endian, IEEE 754-2008, binary32) / A floating point value (64 bits, big endian, IEEE 754-2008, binary64).
How to reproduce
Float tags
/data modify storage mc-171881: float set value -0.0f
/data get storage mc-171881: float
Expected behavior
Storage mc-171881: has the following contents: -0.0f
Actual behavior
Storage mc-171881: has the following contents: 0.0f
Double tags
/data modify storage mc-171881: double set value -0.0d
/data get storage mc-171881: double
Expected behavior
Storage mc-171881: has the following contents: -0.0d
Actual behavior
Storage mc-171881: has the following contents: 0.0d
Code analysis
Since +0.0 and -0.0 are considered identical in IEEE 754, ZERO (the cached 0.0) is returned when value is -0.0.
// net.minecraft.nbt.FloatTag public static FloatTag valueOf(float value) { return value == 0.0f ? ZERO : new FloatTag(value); } // net.minecraft.nbt.DoubleTag public static DoubleTag valueOf(double value) { return value == 0.0d ? ZERO : new DoubleTag(value); }