gpt4 book ai didi

lua - 使用 float 或 double 代替整数

转载 作者:行者123 更新时间:2023-12-04 14:43:52 31 4
gpt4 key购买 nike

我知道 Lua 的默认实现仅使用浮点数,从而避免了在选择使用哪种数学函数变体之前动态确定数字子类型的问题。

我的问题是——如果我尝试在标准 C99 中将整数模拟为 double 数(或浮点数),是否有一种可靠(且简单)的方法来确定可精确表示的最大值是多少?

我的意思是,如果我使用 64 位浮点数来表示整数,我当然不能表示所有 64 位整数(鸽巢原理在这里适用)。如何判断可表示的最大整数?

(尝试列出所有值不是解决方案——例如,如果我在 64 位体系结构中使用 double 数,因为我必须列出 2^{64} 个数字)

谢谢!

最佳答案

可表示的最大整数为 253 (9007199254740992) 对于 64 位 double 数和 224 (16777216) 对于 32 位浮点数。查看 the Wikipedia page for IEEE floating point numbers 上的基数.

在 Lua 中验证这一点非常简单:

local maxdouble = 2^53

-- one less than the maximum can be represented precisely
print (string.format("%.0f",maxdouble-1)) --> 9007199254740991
-- the maximum itself can be represented precisely
print (string.format("%.0f",maxdouble)) --> 9007199254740992
-- one more than the maximum gets rounded down
print (string.format("%.0f",maxdouble+1)) --> 9007199254740992 again

如果我们手边没有 IEEE 定义的字段大小,知道我们对浮点数设计的了解,我们可以使用对可能值的简单循环来确定这些值:

#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#define min(a, b) (a < b ? a : b)
#define bits(type) (sizeof(type) * 8)
#define testimax(test_t) { \
uintmax_t in = 1, out = 2; \
size_t pow = 0, limit = min(bits(test_t), bits(uintmax_t)); \
while (pow < limit && out == in + 1) { \
in = in << 1; \
out = (test_t) in + 1; \
++pow; \
} \
if (pow == limit) \
puts(#test_t " is as precise as longest integer type"); \
else printf(#test_t " conversion imprecise for 2^%d+1:\n" \
" in: %llu\n out: %llu\n\n", pow, in + 1, out); \
}

int main(void)
{
testimax(float);
testimax(double);
return 0;
}

The output of the above code :

float conversion imprecise for 2^24+1:
in: 16777217
out: 16777216

double conversion imprecise for 2^53+1:
in: 9007199254740993
out: 9007199254740992

当然,由于浮点精度的工作方式,当浮点指数增长为正时,64 位 double 可以表示远大于 264 的数字。 The Wikipedia page on double-precision floating-point描述:

Between 252=4,503,599,627,370,496 and 253=9,007,199,254,740,992 the representable numbers are exactly the integers. For the next range, from 253 to 254, everything is multiplied by 2, so the representable numbers are the even ones, etc. Conversely, for the previous range from 251 to 252, the spacing is 0.5, etc.



double 可以保持的绝对最大值在该页面的更下方列出:0x7feffffffffffff,计算为 (1 + (1 − 2−52)) * 21023,或大约 1.7976931348623157e308。

关于lua - 使用 float 或 double 代替整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6060406/

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