Skip to content

Commit 06ade60

Browse files
committed
[css-values-4] Fully sync the trig/pow functions with JS, wrt pos/neg 0. Fixes #4158.
1 parent 314c07f commit 06ade60

File tree

1 file changed

+119
-71
lines changed

1 file changed

+119
-71
lines changed

css-values-4/Overview.bs

Lines changed: 119 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -2632,6 +2632,10 @@ Argument Ranges</h4>
26322632
the result is NaN.
26332633
(See [[#calc-type-checking]] for details on how [=math functions=] handle NaN.)
26342634

2635+
In ''sin(A)'' or ''tan(A)'',
2636+
if A is 0⁻,
2637+
the result is 0⁻.
2638+
26352639
In ''tan(A)'', if A is one of the asymptote values
26362640
(such as ''90deg'', ''270deg'', etc),
26372641
the result must be +∞ for ''90deg'' and all values a multiple of ''360deg'' from that
@@ -2650,22 +2654,78 @@ Argument Ranges</h4>
26502654
if A is less than -1 or greater than 1,
26512655
the result is NaN.
26522656

2657+
In ''acos(A)'',
2658+
if A is exactly 1,
2659+
the result is 0.
2660+
2661+
In ''asin(A)'' or ''atan(A)'',
2662+
if A is 0⁻,
2663+
the result is 0⁻.
2664+
26532665
In ''atan(A)'',
26542666
if A is +∞,
26552667
the result is ''90deg'';
26562668
if A is −∞,
26572669
the result is ''-90deg''.
26582670

2659-
In ''atan2(A, B)'',
2660-
if A and B are both zero,
2661-
the result is ''0deg''.
2662-
If either or both [=calculations=] are infinite,
2663-
the function must return an angle
2664-
as if the infinite value was replaced by ''1'' (for +∞) or ''-1'' (for −∞)
2665-
and the finite value was replaced by ''0'':
2666-
''atan2(finite, ∞)'' must return ''0deg'', as if it were ''atan2(0, 1)'';
2667-
''atan2(∞, ∞)'' must return ''45deg'', as if it were ''atan2(1, 1)'';
2668-
and so on around the circle.
2671+
In ''atan2(Y, X)'',
2672+
the following table gives the results for all unusual argument combinations:
2673+
2674+
<table class=data>
2675+
<thead>
2676+
<tr><td style="border:none" colspan=2><th colspan=6>X
2677+
<tr><td style="border:none" colspan=2><th>−∞ <th>-finite <th>0⁻ <th>0⁺ <th>+finite <th>+∞
2678+
</thead>
2679+
<tr>
2680+
<th rowspan=6 style="border-right:1px solid silver">Y
2681+
<th style="border-right: black 2px solid">−∞
2682+
<td>-135deg
2683+
<td>-90deg
2684+
<td>-90deg
2685+
<td>-90deg
2686+
<td>-90deg
2687+
<td>-45deg
2688+
<tr>
2689+
<th>-finite
2690+
<td>-180deg
2691+
<td>(normal)
2692+
<td>-90deg
2693+
<td>-90deg
2694+
<td>(normal)
2695+
<td>0⁻deg
2696+
<tr>
2697+
<th>0⁻
2698+
<td>-180deg
2699+
<td>-180deg
2700+
<td>-180deg
2701+
<td>0⁻deg
2702+
<td>0⁻deg
2703+
<td>0⁻deg
2704+
<tr>
2705+
<th>0⁺
2706+
<td>180deg
2707+
<td>180deg
2708+
<td>180deg
2709+
<td>0⁺deg
2710+
<td>0⁺deg
2711+
<td>0⁺deg
2712+
<tr>
2713+
<th>+finite
2714+
<td>180deg
2715+
<td>(normal)
2716+
<td>90deg
2717+
<td>90deg
2718+
<td>(normal)
2719+
<td>0⁺deg
2720+
<tr>
2721+
<th>+∞
2722+
<td>135deg
2723+
<td>90deg
2724+
<td>90deg
2725+
<td>90deg
2726+
<td>90deg
2727+
<td>45deg
2728+
</table>
26692729

26702730
Note: All of these behaviors are intended to match the "standard" definitions of these functions
26712731
as implemented by most programming languages,
@@ -2839,77 +2899,57 @@ Exponential Functions: ''pow()'', ''sqrt()'', ''hypot()''</h3>
28392899
Argument Ranges</h4>
28402900

28412901
In ''pow(A, B)'',
2842-
if A is negative,
2902+
if A is negative and finite,
2903+
and B is finite,
28432904
B must be an integer,
28442905
or else the result is NaN.
28452906

2846-
If A and B are both 0,
2847-
the result is 1.
2848-
If A is 0⁺ and B is negative,
2849-
the result is +∞;
2850-
if A is 0⁻ and B is negative,
2851-
the result is −∞.
2852-
2853-
If A or B is infinite,
2907+
If A or B are infinite or 0,
28542908
the following tables give the results:
28552909

2856-
<table class=data>
2910+
<table class=data style="table-layout:fixed">
28572911
<thead>
2858-
<tr><th scope=col colspan=3>A is +∞
2859-
<tr>
2860-
<th>B is < 0
2861-
<th>B is 0
2862-
<th>B is > 0
2912+
<tr><td>
2913+
<th>A is −∞
2914+
<th>A is 0⁻
2915+
<th>A is 0
2916+
<th>A is +∞
28632917
</thead>
28642918
<tr>
2865-
<td>result is 0⁺
2866-
<td>result is 1
2867-
<td>result is +∞
2868-
</table>
2869-
2870-
<table class=data>
2871-
<thead>
2872-
<tr><th scope=col colspan=3>A is −∞
2873-
<tr>
2874-
<th>B is < 0
2875-
<th>B is 0
2876-
<th>B is > 0
2877-
</thead>
2919+
<th>B is −finite
2920+
<td>0⁻ if B is an odd integer, 0⁺ otherwise
2921+
<td>−∞ if B is an odd integer, +∞ otherwise
2922+
<td>+∞
2923+
<td>0⁺
28782924
<tr>
2879-
<td>result is 0⁻ if B is an odd integer, 0⁺ otherwise
2880-
<td>result is 1
2881-
<td>result is −∞ if B is an odd integer, +∞ otherwise
2925+
<th>B is 0
2926+
<td colspan=4>always 1
2927+
<tr>
2928+
<th>B is +finite
2929+
<td>−∞ if B is an odd integer, +∞ otherwise
2930+
<td>0⁻ if B is an odd integer, 0⁺ otherwise
2931+
<td>0⁺
2932+
<td>+∞
28822933
</table>
28832934

28842935
<table class=data>
28852936
<thead>
2886-
<tr><th scope=col colspan=5>B is +∞
2887-
<tr>
2937+
<tr><td>
28882938
<th>A is < -1
28892939
<th>A is -1
28902940
<th>-1 < A < 1
28912941
<th>A is 1
28922942
<th>A is > 1
28932943
</thead>
28942944
<tr>
2945+
<th>B is +∞
28952946
<td>result is +∞
28962947
<td>result is NaN
28972948
<td>result is 0⁺
28982949
<td>result is NaN
28992950
<td>result is +∞
2900-
</table>
2901-
2902-
<table class=data>
2903-
<thead>
2904-
<tr><th scope=col colspan=5>B is −∞
2905-
<tr>
2906-
<th>A is < -1
2907-
<th>A is -1
2908-
<th>-1 < A < 1
2909-
<th>A is 1
2910-
<th>A is > 1
2911-
</thead>
29122951
<tr>
2952+
<th>B is −∞
29132953
<td>result is 0⁺
29142954
<td>result is NaN
29152955
<td>result is +∞
@@ -2920,6 +2960,8 @@ Argument Ranges</h4>
29202960
In ''sqrt(A)'',
29212961
if A is +∞,
29222962
the result is +∞.
2963+
If A is 0⁻,
2964+
the result is 0⁻.
29232965
If A is less than 0,
29242966
the result is NaN.
29252967

@@ -2933,6 +2975,12 @@ Argument Ranges</h4>
29332975
as implemented by most programming languages,
29342976
in particular as implemented in JS.
29352977

2978+
Issue: Per JS, hypot(∞, NaN) yields ∞, and pow(NaN, 0) yields 1.
2979+
This violates the standard calculation rules of NaNs being fully infective.
2980+
Do we want to carry that behavior over as well?
2981+
Or maybe specifically undefine it,
2982+
since it's just error behavior?
2983+
29362984

29372985
<h3 id='calc-syntax'>
29382986
Syntax</h3>
@@ -3114,7 +3162,7 @@ Type Checking</h3>
31143162
and between nested calculations:
31153163

31163164
* Negative zero
3117-
(0<sup></sup>)
3165+
(0)
31183166
can be produced literally by negating a zero
31193167
(''-0''),
31203168
or by a multiplication or division that produces zero
@@ -3131,41 +3179,41 @@ Type Checking</h3>
31313179
they're "censored" away into an "unsigned" zero.
31323180
* ''-0 + -0''
31333181
or ''-0 - 0''
3134-
produces 0<sup></sup>.
3182+
produces 0.
31353183
All other additions or subtractions that would produce a zero
3136-
produce 0<sup>+</sup>.
3137-
* Multiplying or dividing 0<sup></sup> with a positive number
3138-
(including 0<sup>+</sup>)
3184+
produce 0.
3185+
* Multiplying or dividing 0 with a positive number
3186+
(including 0)
31393187
produces a negative result
3140-
(either 0<sup></sup> or −∞),
3141-
while multiplying or dividing 0<sup></sup> with a negative number
3188+
(either 0 or −∞),
3189+
while multiplying or dividing 0 with a negative number
31423190
produces a positive result.
31433191

31443192
(In other words,
3145-
multiplying or dividing with 0<sup></sup>
3193+
multiplying or dividing with 0
31463194
follows standard sign rules.)
3147-
* When comparing 0<sup>+</sup> and 0<sup></sup>,
3148-
0<sup></sup> is less than 0<sup>+</sup>.
3149-
For example, ''min(0, -0)'' must produce 0<sup></sup>,
3150-
''max(0, -0)'' must produce 0<sup>+</sup>,
3151-
and ''clamp(0, -0, 1)'' must produce 0<sup>+</sup>.
3195+
* When comparing 0 and 0,
3196+
0 is less than 0.
3197+
For example, ''min(0, -0)'' must produce 0,
3198+
''max(0, -0)'' must produce 0,
3199+
and ''clamp(0, -0, 1)'' must produce 0.
31523200

31533201
If a <dfn export>top-level calculation</dfn>
31543202
(a [=math function=] not nested inside of another [=math function=])
31553203
would produce a NaN,
31563204
it instead produces +∞.
3157-
If a [=top-level calculation=] would produce 0<sup></sup>,
3205+
If a [=top-level calculation=] would produce 0,
31583206
it instead produces the standard "unsigned" zero.
31593207

31603208
<div class=example>
31613209
For example, ''calc(-5 * 0)'' produces an unsigned zero--
3162-
the calculation resolves to 0<sup></sup>,
3210+
the calculation resolves to 0,
31633211
but as it's a [=top-level calculation=],
31643212
it's then censored to an unsigned zero.
31653213

31663214
On the other hand, ''calc(1 / calc(-5 * 0))'' produces −∞,
31673215
same as ''calc(1 / (-5 * 0))''--
3168-
the inner calc resolves to 0<sup></sup>,
3216+
the inner calc resolves to 0,
31693217
and as it's not a [=top-level calculation=],
31703218
it passes it up unchanged to the outer calc to produce −∞.
31713219
If it was censored into an unsigned zero,

0 commit comments

Comments
 (0)