go into a world in creative, fly
/scoreboard objectives add ReturnX dummy
/tp @p 2097150.3 200.0 0.0
/execute store result score @s ReturnX run data get entity @s Pos[0] 1024.0
/summon area_effect_cloud ~ ~ ~ {Duration:1000,Tags:["return_loc"],Rotation:[20f,20f]}
/execute store result entity @e[limit=1,tag=return_loc] Pos[0] double 0.0009765625 run scoreboard players get @p ReturnX
/execute as @e[limit=1,tag=return_loc] at @s run tp @p ~ ~ ~
Expected: press F3 and see that the player's coordinate still ends in ".3"
Actual: player's coordinate now ends in ".25"
The behavior is what one would get if the intermediate 'scale factor' in the store were using single-precision rather than double-precision floating point, which I expect is the source of the bug. (double-precision has plenty of significant digits to recover the precise value)
Implications for gameplay: you can use this technique of storing a player's coords in the scoreboard to tp them somewhere and then return them to their exact position. However, due to the precision bug, players standing next to a wall get returned to a slightly different position and suffocate in the wall.
EDIT
Here is a simpler-to-understand repro
go into creative, fly, run
summon pig ~ ~ ~ {NoAI:1b,Tags:["piggy"]}
then run a function:
scoreboard objectives add Score dummy
scoreboard objectives setdisplay sidebar Score
tp @p 1.23456789012345 200 0
execute store result score @p Score run data get entity @p Pos[0] 1000000000.0
execute store result entity @e[tag=piggy,limit=1] Pos[0] double 0.000000001 run data get entity @p Pos[0] 1000000000.0
execute store result score @e[tag=piggy,limit=1] Score run data get entity @e[tag=piggy,limit=1] Pos[0] 1000000000.0
Expected:
both guys have score 1234567890
Actual:
pig has score 1234567880
The 1234567880 wrong result is what you get when doing a 32-bit (single-precision) float calculation, whereas the 1234567890 correct result is what you get when doing a 64-bit (double-precision) calculation. And Pos[0] is a double, and called out as "double" in the command.
Attachments
Comments 7
You can see in
[media], that scale
is read as float and not converted to a double.
This can be seen with the following command too, where the scale
is an invalid float, but a valid double.
/execute store result entity @e[type=!player,limit=1] SomeTag double 100000000000000000000000000000000000000000000000 run say a
Possibly easier reproduction steps to prove that no conversion of the scale happens are:
Give yourself an item and throw it on the ground
/give @s stone{Test:1.0}
Run the following commands
/scoreboard players set #largeValue test 1000000000 /execute store result entity @e[type=item,limit=1] Item.tag.Test double 100000000000000000 run scoreboard players get #largeValue test /data get entity @e[type=item,limit=1]
To verify the result the following Java code could be used
System.out.println(String.format(java.util.Locale.ROOT,"%.0f", 1000000000 * 100000000000000000.0f));
System.out.println(String.format(java.util.Locale.ROOT,"%.0f", 1000000000 * (double)100000000000000000.0f));
May I change the report and replace your reproduction steps with the one listed above?
Why not? Your reproduction steps require you being at a certain position.
Could you then at least clean up your report please?
If I perform the command:
/execute store result storage test UUID long 1 run data get entity @p UUIDMost
The value stored will be truncated to the size of int, then casted to a long.
I feel like this bug is related to this ticket. Not sure if this one should be reopened or a new ticket should be created, since it is very similar. (This bug occurred in 20w10a)
That is not a bug, commands are only capable of returning values of type int, which is a limitation hardcoded into brigadier.
This use case is part of why `data modify` was added, which is capable of copying between two NBT locations without going via brigadier, allowing the data to remain unchanged
This may possibly be related to MC-123390