Health is a floating point, but almost always treated as an integer. For instance, a horse with 30 max health and 29.001 current health will have 15/15 hearts full, because there are few damage sources that could kill the horse without dealing 30 damage.
But, a similar horse with, say, 29.3 max health will only have 14 hearts in its health bar, despite also being able to survive 29 full points of damage. If it had a 15th heart, it would be full.
This may have been introduced in 1.19.4; I don't recall breeding horses prior to it and getting any horses with non-integer max health.
To replicate:
summon a horse
do
/attribute @e[type=minecraft:horse,sort=nearest,limit=1] minecraft:generic.max_health base set 29.3
note the health bar with 14 hearts
if you like, deal a full heart of damage to the horse, and all 14 hearts will still be full (27.3 current health is rounded up and displayed as 28)
Linked issues
relates to 2
Comments 4
Does MC-200102 describe your issue?
@ampolive no - this is just about mobs with fractional health points. "how much damage can this mob survive" is the hp rounded up to the next integer, but the hp for the size of the health bar is rounded to the nearest integer (and then from there, down to an even integer, which is what MC-200102 concerns, but to my knowledge that's intentional)
This is by design, a horse with an odd number of health points (15, 17, 19, etc.) does not show the last half-heart.