Open morriscurtis opened 7 months ago
I'm assuming the current implementation is something like this:
var floatValue = Math.Round(byteValue * 100f / 255f) / 100f;
Calculating the correct float values is not a trivial thing (simply changing the factors above from 100f to 1000f won't suffice). There would still be rounding errors.
One simple way of implementing this would be a lookup table. Here is an example implementation of a lookup table for 3 decimal places:
// Generate the lookup table
var lookupTable = new float[256];
var lastNewByteValue = -1;
for (int i = 0; i <= 1000; ++i)
{
var value = i * 0.001f;
var byteValue = (int)(value * 255f);
if (byteValue != lastNewByteValue)
{
lookupTable[byteValue] = value;
lastNewByteValue = byteValue;
}
}
// Print the lookup table
for (int i = 0; i < 256; ++i)
{
Console.WriteLine($"{i:000} => {lookupTable[i]:0.000}");
}
Console.ReadKey(true);
The float values in this lookup table can safely by multiplied by 255 and rounded down to yield the exact byte value of the color. The code basically iterates through all 1001 possible floats and saves the first float that can be safely rounded down into the lookup table.
Microsoft PowerToys version
0.78.0
Installation method
WinGet
Running as admin
No
Area(s) with issue?
ColorPicker
Steps to reproduce
Create a custom float color format in the color picker, eg: As you can see in the example string, the precision is only 2 decimal places. When you multiply this value with 255 to get back to the byte value, it should be the same value as shown in the byte color format. Let's say you pick this shade of red: If you multiply the float values with 255, you do not get the same color: 0.93 255 = 237.15 // Red channel is correct, but... 0.16 255 = 40.8 // Blue channel is only correct if you round, but wrong if you floor the number! 0.22 * 255 = 56.1 // Green channel is wrong, doesn't matter whether you round or floor the number!
✔️ Expected Behavior
The float color format should be able to represent all 256 shades of a color channel exactly.
❌ Actual Behavior
The picked color is in many cases not exactly represented by the 2 decimal points of the current float color format. The range from 0.00 to 1.00 contains 101 possible values, while the range from 0 to 255 contains 256 values. It is impossible to uniquely map 256 values into just 101. The range from 0.000 to 1.000 contains 1001 values, so there an exact mapping is possible.
Other Software
No response