gpt4 book ai didi

c - 这个数字如何表示为 2^-22*(1/10) 的倍数?那是怎么推导出来的?

转载 作者:太空宇宙 更新时间:2023-11-04 04:41:36 25 4
gpt4 key购买 nike

我在刷新二进制和 float 时遇到了以下示例:
0.1 表示为:0.0001100110011001100110011[0011] 括号中的部分重复。
如果我们将此表示形式四舍五入,我们将得到:
x = 0.00011001100110011001101(十进制为 0.10000002384185791015625)。

差x-0.1有二进制表示:
0.0000000000000000000000000[1100] 即(十进制的 0.00000002384185791015625)。
现在如何将此值表示为 2^x* 1/10 的分数?
我读到它基本上是 2^-22*(1/10) 但我看不出我们如何推导出这个。有什么帮助吗?
注:数字四舍五入为23位(但x-0.1例子中的1在第25位)

更新:
我的问题不是 1/10 是如何表示的。
但是如何从位字符串 0.0000000000000000000000000[1100] 中我们可以用“人类”格式(即十进制)表示它。在这种情况下,它是 2^-22*(1/10)

最佳答案

使用 n 位二进制数重复的属性,其值为

pattern *= (1 << BitWidth)/ ((1 << BitWidth) - 1);

继续简化分数。

unsigned gcd(unsigned a, unsigned b) {
if (b == 0)
return a;
else
return gcd(b, a % b);
}

// Print result & return NULL on success, else point to problem in input.
const char *Cratylus_s(const char *src) {

// parse the input
const char *s = src;
while (*s == '0')
s++;
if (*s != '.') {
return s;
}
s++;
const char *rp = s; // radix point
while (*s == '0')
s++;
int offset = s - rp;
if (*s != '[') {
return s;
}
s++;
unsigned bin = 0;
unsigned pow2 = 0;
while (*s == '0' || *s == '1') {
bin = bin * 2 + *s - '0';
pow2++;
s++;
}
if (*s != ']' || *++s != '\0') {
return s;
}

// multiply `bin` by (1 << pow2)/((1 << pow2 - 1)
unsigned num = bin * (1 << pow2);
unsigned den = (1 << pow2) - 1;
const char *format = "2^%d*(%u/%u)\n";
printf(format, offset + pow2, num, den); // 2^29*(192/15)

// simplify
unsigned common = gcd(num, den);
num /= common;
den /= common;
printf(format, offset + pow2, num, den); // 2^29*(64/5)

// find powers of 10
for (unsigned d = den; d && d % 5 == 0; d /= 5) {
num *= 2;
den *= 2;
}

// find powers of 2
for (unsigned n = num; n && n % 2 == 0; n /= 2) {
num /= 2;
offset--;
}
printf(format, offset + pow2, num, den); // 2^-22*(1/10)
return NULL;

}

void Cratylus_test(const char *s) {
printf("'%s'\n", s);
const char *t = Cratylus_s(s);
printf("'%s'\n", t ? t : "OK");
}

int main(void) {
Cratylus_test("0.0000000000000000000000000[1100]");
Cratylus_test("0.000000000000000[0110]");
return 0;
}

'0.0000000000000000000000000[1100]'
2^29*(192/15)
2^29*(64/5)
2^22*(1/10)
'OK'
'0.000000000000000[0110]'
2^19*(96/15)
2^19*(32/5)
2^13*(1/10)
'OK'

关于c - 这个数字如何表示为 2^-22*(1/10) 的倍数?那是怎么推导出来的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25879314/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com