Skip to main content

I’ve created a custom plugin to export my Figma variables.
I have an opacity variable that is set to 0.8
 



However, when I export it, it gets exported with a value of 0.800000011920929
 

const variable = await figma.variables.getVariableByIdAsync(variableId);
const { name, valuesByMode } = variable;

console.log({name});
console.log({valuesByMode});

 

When I use “nicer” numbers, like 0.25, 0.5, 0.75 or 1, the rounding error does not happen, but it does with pretty much any other numbers.

This is caused by how non-integer numbers are stored in memory. For floating point numbers (that aren’t a nice sum of powers of two), you will run into this issue every time they’re displayed.

Pretty much all digital systems follow IEEE 754, in which those numbers are represented like this:

Decimal Binary (32-bit)
0.25 0b00111110100000000000000000000000
0.5 0b00111111000000000000000000000000
0.75 0b00111111010000000000000000000000
0.8 0b00111111010011001100110011001101

 

As you can see, the first two numbers are represented precisely - there are lots of zeros at the end, because we don’t even need all 32 bits to store them. They’re sums of powers of two:

  • 0.25 = 2^(-2)
  • 0.5 = 2^(-1)
  • 0.75 = 2^(-1) + 2^(-2)

However, 0.8 isn’t equal to any sum of powers of two. Best you can do is approximate it with many smaller powers, which you can see on the binary representation above - there’s a sequence of 0011 that’s endlessly repeating.

It’s not a bug in Figma, but how computers store floating point numbers. You can safely use this value used by Figma, and round it to the desired precision on your end, at the last step of processing (e.g. when displaying the number to the user), or convert it to a string.


Reply