Skip to content

Commit b0f70d9

Browse files
authored
Use native round (#240)
1 parent 414516f commit b0f70d9

File tree

9 files changed

+32
-71
lines changed

9 files changed

+32
-71
lines changed

lib/sass/value/color.rb

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -318,32 +318,32 @@ def ==(other)
318318

319319
if legacy?
320320
return false unless other.legacy?
321-
return false unless FuzzyMath.equals_nilable(other.alpha_or_nil, alpha_or_nil)
321+
return false unless FuzzyMath.equals(other.alpha_or_nil, alpha_or_nil)
322322

323323
if _space == other._space
324-
FuzzyMath.equals_nilable(other.channel0_or_nil, channel0_or_nil) &&
325-
FuzzyMath.equals_nilable(other.channel1_or_nil, channel1_or_nil) &&
326-
FuzzyMath.equals_nilable(other.channel2_or_nil, channel2_or_nil)
324+
FuzzyMath.equals(other.channel0_or_nil, channel0_or_nil) &&
325+
FuzzyMath.equals(other.channel1_or_nil, channel1_or_nil) &&
326+
FuzzyMath.equals(other.channel2_or_nil, channel2_or_nil)
327327
else
328328
_to_space(Space::RGB) == other._to_space(Space::RGB)
329329
end
330330
else
331331
other._space == _space &&
332-
FuzzyMath.equals_nilable(other.channel0_or_nil, channel0_or_nil) &&
333-
FuzzyMath.equals_nilable(other.channel1_or_nil, channel1_or_nil) &&
334-
FuzzyMath.equals_nilable(other.channel2_or_nil, channel2_or_nil) &&
335-
FuzzyMath.equals_nilable(other.alpha_or_nil, alpha_or_nil)
332+
FuzzyMath.equals(other.channel0_or_nil, channel0_or_nil) &&
333+
FuzzyMath.equals(other.channel1_or_nil, channel1_or_nil) &&
334+
FuzzyMath.equals(other.channel2_or_nil, channel2_or_nil) &&
335+
FuzzyMath.equals(other.alpha_or_nil, alpha_or_nil)
336336
end
337337
end
338338

339339
# @return [Integer]
340340
def hash
341341
@hash ||= [
342-
_space,
343-
channel0_or_nil&.finite? ? (channel0_or_nil * FuzzyMath::INVERSE_EPSILON).round : channel0_or_nil, # rubocop:disable Security/CompoundHash
344-
channel1_or_nil&.finite? ? (channel1_or_nil * FuzzyMath::INVERSE_EPSILON).round : channel1_or_nil, # rubocop:disable Security/CompoundHash
345-
channel2_or_nil&.finite? ? (channel2_or_nil * FuzzyMath::INVERSE_EPSILON).round : channel2_or_nil, # rubocop:disable Security/CompoundHash
346-
alpha_or_nil&.finite? ? (alpha_or_nil * FuzzyMath::INVERSE_EPSILON).round : alpha_or_nil # rubocop:disable Security/CompoundHash
342+
_space.name,
343+
FuzzyMath._round(channel0_or_nil),
344+
FuzzyMath._round(channel1_or_nil),
345+
FuzzyMath._round(channel2_or_nil),
346+
FuzzyMath._round(alpha_or_nil)
347347
].hash
348348
end
349349

lib/sass/value/color/gamut_map_method/clip.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def _clamp_channel(value, channel)
2929

3030
case channel
3131
when LinearChannel
32-
FuzzyMath.clamp_like_css(value, channel.min, channel.max)
32+
FuzzyMath._clamp_like_css(value, channel.min, channel.max)
3333
else
3434
value
3535
end

lib/sass/value/color/space/a98_rgb.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ def initialize
1717
end
1818

1919
def to_linear(channel)
20-
FuzzyMath.sign(channel) * (channel.abs**(563 / 256.0))
20+
(channel <=> 0) * (channel.abs**(563 / 256.0))
2121
end
2222

2323
def from_linear(channel)
24-
FuzzyMath.sign(channel) * (channel.abs**(256 / 563.0))
24+
(channel <=> 0) * (channel.abs**(256 / 563.0))
2525
end
2626

2727
private

lib/sass/value/color/space/prophoto_rgb.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ def initialize
1818

1919
def to_linear(channel)
2020
abs = channel.abs
21-
abs <= 16 / 512.0 ? channel / 16.0 : FuzzyMath.sign(channel) * (abs**1.8)
21+
abs <= 16 / 512.0 ? channel / 16.0 : (channel <=> 0) * (abs**1.8)
2222
end
2323

2424
def from_linear(channel)
2525
abs = channel.abs
26-
abs >= 1 / 512.0 ? FuzzyMath.sign(channel) * (abs**(1 / 1.8)) : 16 * channel
26+
abs >= 1 / 512.0 ? (channel <=> 0) * (abs**(1 / 1.8)) : 16 * channel
2727
end
2828

2929
private

lib/sass/value/color/space/rec2020.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ def initialize
2828

2929
def to_linear(channel)
3030
abs = channel.abs
31-
abs < BETA * 4.5 ? channel / 4.5 : FuzzyMath.sign(channel) * (((abs + ALPHA - 1) / ALPHA)**(1 / 0.45))
31+
abs < BETA * 4.5 ? channel / 4.5 : (channel <=> 0) * (((abs + ALPHA - 1) / ALPHA)**(1 / 0.45))
3232
end
3333

3434
def from_linear(channel)
3535
abs = channel.abs
36-
abs > BETA ? FuzzyMath.sign(channel) * ((ALPHA * (abs**0.45)) - (ALPHA - 1)) : 4.5 * channel
36+
abs > BETA ? (channel <=> 0) * ((ALPHA * (abs**0.45)) - (ALPHA - 1)) : 4.5 * channel
3737
end
3838

3939
private

lib/sass/value/color/space/utils.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ module Utils
3737
# @return [Numeric]
3838
def srgb_and_display_p3_to_linear(channel)
3939
abs = channel.abs
40-
abs < 0.04045 ? channel / 12.92 : FuzzyMath.sign(channel) * (((abs + 0.055) / 1.055)**2.4)
40+
abs < 0.04045 ? channel / 12.92 : (channel <=> 0) * (((abs + 0.055) / 1.055)**2.4)
4141
end
4242

4343
# The algorithm for converting a single `srgb` or `display-p3` channel to
@@ -46,7 +46,7 @@ def srgb_and_display_p3_to_linear(channel)
4646
# @return [Numeric]
4747
def srgb_and_display_p3_from_linear(channel)
4848
abs = channel.abs
49-
abs <= 0.0031308 ? channel * 12.92 : FuzzyMath.sign(channel) * ((1.055 * (abs**(1 / 2.4))) - 0.055)
49+
abs <= 0.0031308 ? channel * 12.92 : (channel <=> 0) * ((1.055 * (abs**(1 / 2.4))) - 0.055)
5050
end
5151

5252
# Converts a Lab or OKLab color to LCH or OKLCH, respectively.

lib/sass/value/fuzzy_math.rb

Lines changed: 6 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,12 @@ module Sass
44
module Value
55
# Sass's {FuzzyMath} module.
66
module FuzzyMath
7-
PRECISION = 10
8-
9-
EPSILON = 10**(-PRECISION - 1)
10-
11-
INVERSE_EPSILON = 10**(PRECISION + 1)
7+
PRECISION = 11
128

139
module_function
1410

1511
def equals(number1, number2)
16-
return true if number1 == number2
17-
18-
(number1 - number2).abs <= EPSILON &&
19-
(number1 * INVERSE_EPSILON).round ==
20-
(number2 * INVERSE_EPSILON).round
21-
end
22-
23-
def equals_nilable(number1, number2)
24-
return true if number1 == number2
25-
return false if number1.nil? || number2.nil?
26-
27-
(number1 - number2).abs <= EPSILON &&
28-
(number1 * INVERSE_EPSILON).round ==
29-
(number2 * INVERSE_EPSILON).round
12+
number1 == number2 || number1.round(PRECISION) == number2.round(PRECISION)
3013
end
3114

3215
def less_than(number1, number2)
@@ -49,31 +32,13 @@ def integer?(number)
4932
return false unless number.finite?
5033
return true if number.integer?
5134

52-
equals((number - 0.5).abs % 1, 0.5)
35+
number.round == number.round(PRECISION)
5336
end
5437

5538
def to_i(number)
5639
integer?(number) ? number.round : nil
5740
end
5841

59-
def round(number)
60-
if number.positive?
61-
less_than(number % 1, 0.5) ? number.floor : number.ceil
62-
else
63-
less_than_or_equals(number % 1, 0.5) ? number.floor : number.ceil
64-
end
65-
end
66-
67-
def sign(number)
68-
if number.positive?
69-
1
70-
elsif number.negative?
71-
-1
72-
else
73-
0
74-
end
75-
end
76-
7742
def between(number, min, max)
7843
return min if equals(number, min)
7944
return max if equals(number, max)
@@ -89,16 +54,12 @@ def assert_between(number, min, max, name)
8954
raise Sass::ScriptError.new("#{number} must be between #{min} and #{max}.", name)
9055
end
9156

92-
def clamp_like_css(number, lower_bound, upper_bound)
57+
def _clamp_like_css(number, lower_bound, upper_bound)
9358
number.to_f.nan? ? lower_bound : number.clamp(lower_bound, upper_bound)
9459
end
9560

96-
def hash(number)
97-
if number.finite?
98-
(number * INVERSE_EPSILON).round.hash
99-
else
100-
number.hash
101-
end
61+
def _round(number)
62+
number&.finite? ? number.round(PRECISION).to_f : number
10263
end
10364
end
10465

lib/sass/value/number.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def ==(other)
9999

100100
# @return [Integer]
101101
def hash
102-
@hash ||= FuzzyMath.hash(canonical_units_value)
102+
@hash ||= FuzzyMath._round(canonical_units_value).hash
103103
end
104104

105105
# @return [::Boolean]

spec/spec_helper.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
supports_block_expectations
4545
end
4646

47-
epsilon = Sass::Value.const_get(:FuzzyMath)::EPSILON
47+
precision = Sass::Value.const_get(:FuzzyMath)::PRECISION - 1
4848

4949
RSpec::Matchers.matcher :fuzzy_eq do |expected|
5050
match do |actual|
@@ -56,7 +56,7 @@
5656
expect(actual.channel_missing?('alpha')).to eq(expected.channel_missing?('alpha'))
5757
expect(actual.alpha).to fuzzy_eq(expected.alpha)
5858
when Numeric
59-
expect(actual).to be_within(epsilon).of(expected)
59+
expect(actual).to be_within(((10**-precision) / 2)).of(expected.round(precision))
6060
else
6161
expect(actual).to eq(expected)
6262
end
@@ -67,7 +67,7 @@
6767
match do |actual|
6868
expect(actual).to match_array(expected.map do |obj|
6969
if obj.is_a?(Numeric)
70-
a_value_within(epsilon).of(obj)
70+
a_value_within((10**-precision) / 2).of(obj.round(precision))
7171
else
7272
obj
7373
end

0 commit comments

Comments
 (0)