-
Notifications
You must be signed in to change notification settings - Fork 398
Open
Description
For x > e2 and e1 < e2, linearstep(e1, e2, x) should return 1.0. This however isn't guaranteed by the implementation in stdosl.h, due to possible rounding errors.
I think on platforms that exactly follow IEEE this is in fact guaranteed, but many platforms, especially with GPU targets, have optimisations with weaker error guarantees than what is required by IEEE floating point math. (see for example div.approx in PTX)
This is the implementation in stdosl.h:
float linearstep (float edge0, float edge1, float x) {
float result;
if (edge0 != edge1) {
float xclamped = clamp (x, edge0, edge1);
result = (xclamped - edge0) / (edge1 - edge0);
} else { // special case: edges coincide
result = step (edge0, x);
}
return result;
}
A possible fix: since in the if branch we know edge0 is not equal to edge1, the following is mathematically equivalent, but it is logically guaranteed to return exactly 1 for x > e2 and e1 < e2:
if (edge0 != edge1) {
result = clamp((x - edge0) / (edge1 - edge0), 0, 1);
} else ....
Metadata
Metadata
Assignees
Labels
No labels