是否有一个函数可以检索范围内可用的不同值的数量?
Is there a function to retrieve the number of available distinct values within a range?
我正在制作的应用程序中使用双精度浮点变量。
我标准化了一些值范围。从(例如;我有很多范围)-48.0
到 48.0
到 0.0
到 1.0
,使用这个简单的函数:
double ToNormalizedParam(double nonNormalizedValue, double min, double max, double shape) {
return pow((nonNormalizedValue - min) / (max - min), 1.0 / shape);
}
我想知道从一个范围映射到另一个范围的可用值和不同值的区别。
C++有现成的函数吗?我查看了 numeric_limits
,但找不到任何有用的东西。
给定一个带指数 e
和尾数 m
的正 IEEE 754 双精度浮点数,两者都被解释为整数,不同的值(不包括非规范化值)小于但大于比零正好是 m + (e - 1) * 2^52
.
可以像这样提取
#include<iostream>
#include<tuple>
#include<cstdint>
#include<cstring>
using std::uint64_t;
std::tuple<uint64_t, uint64_t, uint64_t> explode(double d)
{
static_assert(sizeof(double) == 8);
uint64_t u;
std::memcpy(&u, &d, sizeof(d));
return { (u & 0x8000000000000000) >> 63,
(u & 0x7FF0000000000000) >> 52,
u & 0x000FFFFFFFFFFFFF };
}
uint64_t distinct(double d)
{
auto [_, e, m] = explode(d);
return m + ((e - 1) << 52);
}
int main()
{
std::cout << "[-48, 48]: " << 2 * distinct(48) << "\n[0, 1]: " << distinct(1) << '\n';
}
Is there a ready-to-go function in C++?
也许吧。如果没有,很容易形成一个函数来为每个 double
值分配一个序列号。
假设字节序和大小匹配 FP/integer 和像 double64 这样的典型 FP 布局,下面是有效的 -INF
到 INF
。
// Return a sequence number for each `double` value.
// Numerically sequential `double` values will have successive (+1) sequence numbers.
uint64_t double_sequence(double x) {
uint64_t u64;
memcpy(&u64, &x, sizeof u64);
if (u64 & 0x8000000000000000) {
u64 ^= 0x8000000000000000;
return 0x8000000000000000 - u64;
}
return u64 + 0x8000000000000000;
}
Is there a function to retrieve the number of available distinct values within a range?
只需减去序号即可。 +1 或 -1 取决于 open or closed range.
double_sequence(1.0) - double_sequence(0.0) + 1 --> 0x3ff0000000000001
double_sequence(48.0) - double_sequence(-48.0) + 1 --> 0x8090000000000001
备注:
请记住,FP 总体呈对数分布,并且在 2 的幂内呈线性。
对于所有 FP 的大约一半,|x| < 1.0
.
FP 数字 0.5 到 1.0 与 16.0 到 32.0 之间的一样多。
[-48.0 ... 48.0]
范围内的 double
是 [0.0 ... 1.0]
范围内的两倍多,这主要是由于负值。
我正在制作的应用程序中使用双精度浮点变量。
我标准化了一些值范围。从(例如;我有很多范围)-48.0
到 48.0
到 0.0
到 1.0
,使用这个简单的函数:
double ToNormalizedParam(double nonNormalizedValue, double min, double max, double shape) {
return pow((nonNormalizedValue - min) / (max - min), 1.0 / shape);
}
我想知道从一个范围映射到另一个范围的可用值和不同值的区别。
C++有现成的函数吗?我查看了 numeric_limits
,但找不到任何有用的东西。
给定一个带指数 e
和尾数 m
的正 IEEE 754 双精度浮点数,两者都被解释为整数,不同的值(不包括非规范化值)小于但大于比零正好是 m + (e - 1) * 2^52
.
可以像这样提取
#include<iostream>
#include<tuple>
#include<cstdint>
#include<cstring>
using std::uint64_t;
std::tuple<uint64_t, uint64_t, uint64_t> explode(double d)
{
static_assert(sizeof(double) == 8);
uint64_t u;
std::memcpy(&u, &d, sizeof(d));
return { (u & 0x8000000000000000) >> 63,
(u & 0x7FF0000000000000) >> 52,
u & 0x000FFFFFFFFFFFFF };
}
uint64_t distinct(double d)
{
auto [_, e, m] = explode(d);
return m + ((e - 1) << 52);
}
int main()
{
std::cout << "[-48, 48]: " << 2 * distinct(48) << "\n[0, 1]: " << distinct(1) << '\n';
}
Is there a ready-to-go function in C++?
也许吧。如果没有,很容易形成一个函数来为每个 double
值分配一个序列号。
假设字节序和大小匹配 FP/integer 和像 double64 这样的典型 FP 布局,下面是有效的 -INF
到 INF
。
// Return a sequence number for each `double` value.
// Numerically sequential `double` values will have successive (+1) sequence numbers.
uint64_t double_sequence(double x) {
uint64_t u64;
memcpy(&u64, &x, sizeof u64);
if (u64 & 0x8000000000000000) {
u64 ^= 0x8000000000000000;
return 0x8000000000000000 - u64;
}
return u64 + 0x8000000000000000;
}
Is there a function to retrieve the number of available distinct values within a range?
只需减去序号即可。 +1 或 -1 取决于 open or closed range.
double_sequence(1.0) - double_sequence(0.0) + 1 --> 0x3ff0000000000001
double_sequence(48.0) - double_sequence(-48.0) + 1 --> 0x8090000000000001
备注:
请记住,FP 总体呈对数分布,并且在 2 的幂内呈线性。
对于所有 FP 的大约一半,|x| < 1.0
.
FP 数字 0.5 到 1.0 与 16.0 到 32.0 之间的一样多。
[-48.0 ... 48.0]
范围内的 double
是 [0.0 ... 1.0]
范围内的两倍多,这主要是由于负值。