我有兴趣为[0,1(范围内的两个二重计算函数int bit_Delta(double p1, double p2)
。该函数返回点后两个二重偏离的二进制索引。
例如,1/2 = 0.10
为二进制,3/4=0.11
为二进制。所以bit_delta(0.5, 0.75)
应该返回2
,因为它们的第一个数字(1(是相同的,但第二个数字是它们不同的第一个位数。
我考虑过分别计算每个二重的尾数和指数。如果指数不同,我想我可以做到,但如果指数相同,我不知道如何使用尾数。有什么想法吗?
如果两个值都高于0.5
===>否则如果两者都低于0.5
==>两者都具有未设置的第一位。
如果两者都高于0.5
,减去0.5
和一半的trehold,继续,直到找到阈值,其中值不是都高于或都低于阈值。
#include <iostream>
int bit_delta(double a, double b)
{
if (a == b) return -1;
double treshold = 0.5;
for (int digit = 1; digit < 20; digit++, treshold /= 2)
{
if (a < treshold && b < treshold)
{
}
else if (a >= treshold && b >= treshold)
{
a -= treshold;
b -= treshold;
}
else
return digit;
}
return 20; //compare more than 20 digits does not make sense for a double
}
int main()
{
std::cout << bit_delta(0.25, 0.75) << std::endl;
std::cout << bit_delta(0.5, 0.75) << std::endl;
std::cout << bit_delta(0.7632, 0.751) << std::endl;
}
此代码返回1 2 7
。
以下思想基于双值到定点算术的转换,将整数与XOR进行比较,并计算相等的最高有效位。
#include <bit>
int bit_delta(double p1, double p2)
{
unsigned int i1 = static_cast<unsigned int>(p1 * 0x80000000U);
unsigned int i2 = static_cast<unsigned int>(p2 * 0x80000000U);
return std::countl_zero(i1 ^ i2);
}
它返回的结果介于1.之间。。32.
在正输入p1
和p2
低于1.
的情况下,i1
和i2
的MSB将始终为零,这是获得正确计数所必需的。
通过使用unsigned long long int
而不是unsigned int
,可以将精度提高到53(即double
数字的精度(。
bit
标头中包含的函数countl_zero
是在C++20中引入的。