Date: Sun, 13 Apr 2025 20:24:58 +0200
I do not. I'm not smart enough to consider all the different edge cases
and make up a general recommendation as to what should happen. And I'm
also not really familiar with how to handle floating point precision
values. It's more of a feature request and looking to see what others
think of the idea. But maybe something like this:
- lerp_inv normalizes value x in the range [a, b] to [0, 1], such that
std::lerp(a, b, std::lerp_inv(a, b, x)) == x
- the return type shall be float if all inputs are integers, otherwise
std::common_type_t for all input types
- if a == +/-inf, and b ==+/-inf, return nan, matches naive implementation
- if a == b, and x == a, then return 0.5? 0.0? 1.0? nan? the value of a
4th parameter that is defaulted to any of those?, does not match naive
implementation (would result in nan)
- if a == b, and x < a, then return -inf, matches naive implementation
- if a == b, and x > a, then return +inf, matches naive implementation
- if a == -inf and x != +/- inf, then return 1.0, maybe nan to keep
complexity low
- if a == +inf and x != +/- inf, then return -1.0, maybe nan to keep
complexity low
- if b == -inf and x != +/- inf, then return -0.0, maybe nan to keep
complexity low
- if b == +inf and x != +/- inf, then return 0.0, maybe nan to keep
complexity low
- if a or b is +/- inf and x == +/- inf, then return nan, matches naive
implementation
maybe also add a clamped version
So perhaps, and probably wrong, something like this
```cpp
constexpr auto lerp_inv(const auto a, const auto b, const auto x, const
std::common_type_t<decltype(a), decltype(b), decltype(x), float>
ambiguous_result = 0.5)
{
using T = std::common_type_t<decltype(a), decltype(b), decltype(x),
float>;
if (a == b && x == a) return ambiguous_result;
return (static_cast<T>(x) - static_cast<T>(a)) / (
static_cast<T>(b) - static_cast<T>(a) );
}
```
https://godbolt.org/z/j81bP64qP
Though obviously it doesn't really do what lerp does. Not sure why, or
how to fix it.
On 13.04.25 18:38, Giuseppe D'Angelo via Std-Proposals wrote:
> Hi,
>
> On 13/04/2025 17:23, Paul Meckel via Std-Proposals wrote:
>> for lerp_inv(a, b, x) it should hold true
>>
>> lerp(a, b, lerp_inv(a, b, x)) == x
>>
>> The naive implementation is
>>
>> ```cpp
>> template <typename T>
>> requires std::is_arithmetic_v<T> // can we also get concept
>> std::arithmetic, please?
>> constexpr T lerp_inv(const T a, const T b, const T x) noexcept {
>> return (x - a) / (b - a);
>> }
>> ```
>
> Do you have a non-naive implementation available, that also satisfies
> a set of useful properties?
>
> std::lerp got added by
>
> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0811r3.html
>
> That paper discusses an interesting set of properties that lerp should
> have, and also provided a reference implementation. That reference
> implementation is the one actually used by libstdc++ and libc++:
>
> https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/c_global/cmath#L3840
>
>
> https://github.com/llvm/llvm-project/blob/main/libcxx/include/cmath#L576
>
> You should provide the same (rationale and implementation), and with
> that you can turn this idea into a paper.
>
> Thanks,
>
>
and make up a general recommendation as to what should happen. And I'm
also not really familiar with how to handle floating point precision
values. It's more of a feature request and looking to see what others
think of the idea. But maybe something like this:
- lerp_inv normalizes value x in the range [a, b] to [0, 1], such that
std::lerp(a, b, std::lerp_inv(a, b, x)) == x
- the return type shall be float if all inputs are integers, otherwise
std::common_type_t for all input types
- if a == +/-inf, and b ==+/-inf, return nan, matches naive implementation
- if a == b, and x == a, then return 0.5? 0.0? 1.0? nan? the value of a
4th parameter that is defaulted to any of those?, does not match naive
implementation (would result in nan)
- if a == b, and x < a, then return -inf, matches naive implementation
- if a == b, and x > a, then return +inf, matches naive implementation
- if a == -inf and x != +/- inf, then return 1.0, maybe nan to keep
complexity low
- if a == +inf and x != +/- inf, then return -1.0, maybe nan to keep
complexity low
- if b == -inf and x != +/- inf, then return -0.0, maybe nan to keep
complexity low
- if b == +inf and x != +/- inf, then return 0.0, maybe nan to keep
complexity low
- if a or b is +/- inf and x == +/- inf, then return nan, matches naive
implementation
maybe also add a clamped version
So perhaps, and probably wrong, something like this
```cpp
constexpr auto lerp_inv(const auto a, const auto b, const auto x, const
std::common_type_t<decltype(a), decltype(b), decltype(x), float>
ambiguous_result = 0.5)
{
using T = std::common_type_t<decltype(a), decltype(b), decltype(x),
float>;
if (a == b && x == a) return ambiguous_result;
return (static_cast<T>(x) - static_cast<T>(a)) / (
static_cast<T>(b) - static_cast<T>(a) );
}
```
https://godbolt.org/z/j81bP64qP
Though obviously it doesn't really do what lerp does. Not sure why, or
how to fix it.
On 13.04.25 18:38, Giuseppe D'Angelo via Std-Proposals wrote:
> Hi,
>
> On 13/04/2025 17:23, Paul Meckel via Std-Proposals wrote:
>> for lerp_inv(a, b, x) it should hold true
>>
>> lerp(a, b, lerp_inv(a, b, x)) == x
>>
>> The naive implementation is
>>
>> ```cpp
>> template <typename T>
>> requires std::is_arithmetic_v<T> // can we also get concept
>> std::arithmetic, please?
>> constexpr T lerp_inv(const T a, const T b, const T x) noexcept {
>> return (x - a) / (b - a);
>> }
>> ```
>
> Do you have a non-naive implementation available, that also satisfies
> a set of useful properties?
>
> std::lerp got added by
>
> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0811r3.html
>
> That paper discusses an interesting set of properties that lerp should
> have, and also provided a reference implementation. That reference
> implementation is the one actually used by libstdc++ and libc++:
>
> https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/c_global/cmath#L3840
>
>
> https://github.com/llvm/llvm-project/blob/main/libcxx/include/cmath#L576
>
> You should provide the same (rationale and implementation), and with
> that you can turn this idea into a paper.
>
> Thanks,
>
>
Received on 2025-04-13 18:25:05