Incorrect Color components transformation

Hi! Can somebody explain why does this happen?

var color = new Color(0f, 0f, 0f, 0.7f);
var integer1 = (int) (100f * 0.7f); // 70 as expected
var integer2 = (int) (100f * color.a); // 69! WTF?

Bug created: https://fogbugz.unity3d.com/default.asp?1368927_u4t12boc6u3e5kvf

Welcome to floating point inaccuracies. You’ll get used to it. That’s why you don’t compare floating point numbers for equality, as it is not possible to represent 0.7 precisely in a non-infinite-length binary number.

It’s definitely not a float issue, it’s about how Unity’s Color stores it.

I don’t know for sure, but my guess would be that Unity stores every channel of a Color struct not as floats, but as 8 bits. So precision is even lower than that of a float. So Kurt-Dekker is right (I think) in his assessment that it’s a precision issue, it’s just not a float precision issue.

I suppose color channels are stored this way, because four channels (RGBA) would make a nice 32 bits chunk, and thats a pretty common way to store colors in many softwares. So I can’t swear that Unity works that way as well, but it is likely.

It is highly likely considering the castless conversions available between Color and Color32.

Under it all it’s likely just a System.Int32 as far as the back-end storage, a good old RGBA quadlet.

Color is a struct with float fields (not byte fields like Color32), it should work as a regular struct or class.