For various reasons, my application has floating point color components instead of integers. Things looked good, but when I wrote some unit tests I discovered some tiny inconsistencies - I worked around them easily but wanted to put this forth here.

The issue is juce::Color::fromFloatRGBA which uses juce::ColourHelpers::floatToUInt8 - the key line of code is this one:

return n <= 0.0f ? 0 : (n >= 1.0f ? 255 : (uint8) (n * 255.0f));

If n is always hard-bounded above by 1.0f, you can only get 255 if n is exactly equal to 1.0f. But as you know, if you are testing for equality with floating point numbers, you are in a state of sin...

And indeed, I ran into cases where I did a lot of calculations and got numbers like r=0.9999247, which gets truncated to 254.

I used the following tweak. It's not theoretically correct but rounding isn't either - and it definitely solves my issues and should give the right answer nearly all the time or at least not make things worse:

static const float ROUNDING_ADJUSTMENT = 0.1f; static const float COLOUR_MODULUS = 255.0f + ROUNDING_ADJUSTMENT; static uint8 floatToUInt8(const float n) { return static_cast<uint8>(jmax(0.0f, jmin(255.0f, n * COLOUR_MODULUS)); }