- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
OpenBSD 的 C 库有一个名为 reallocarray(3) 的扩展名哪个realloc(array, size*nmemb)
如果乘法溢出而不会爆炸。 The implementation包含此片段:
/*
* This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
* if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
*/
#define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 4))
Over on Programmers.SE该计算的修改版本因技术错误而受到影响。 4
显然应该是 CHAR_BIT/2
,但这不是唯一的问题。假设一个不寻常的 ABI,其中 size_t
有填充位。 (这并非难以置信:考虑一个具有 32 位寄存器但具有 24 位地址空间的微 Controller 。)那么 SIZE_MAX
小于 1 << (sizeof(size_t)*CHAR_BIT)
[无限精度算术] 计算错误。
所以,问题:你能计算出floor(sqrt(SIZE_MAX+1))
吗?仅使用 C99 整数常量表达式算法,不对 ABI 做任何假设,除了 C99 要求的内容以及您可以从中学到的内容 <limits.h>
?注意 SIZE_MAX
可能等于 UINTMAX_MAX
,即可能没有任何类型可以表示 SIZE_MAX+1
没有溢出。
编辑:我认为 SIZE_MAX
对于某个正整数 n 要求为 2n − 1,但不一定必须是 22n − 1 — 考虑 S/390,其中一个 ABI 具有 31 位地址空间。因此:如果sqrt(SIZE_MAX+1)
不是整数,则所需结果(给定此常量的使用方式)为 floor()
的真实值(value)。
最佳答案
常量 SIZE_MAX
是非负的,类型为 size_t
.为简短起见,我将定义:
#define S SIZE_MAX
数学值S+1
正如您所指出的,超出或可能超出任何整数类型的范围。
我会写 S1
对于 S+1
的数学值.
如果我们考虑 S1
的对数(如果需要,以 2 为底) ,那么我们有:
logarithm(sqrt(S1)) == (1.0/2.0) logarithm(S1)
另一方面,在几乎可以肯定的每种现实情况下,我们都会有 S
表示为只有 1
的二进制数位。编号b
通常,这些位的数量是 CHAR_BIT
乘以 2 的幂,乘以 CHAR_BIT:16、32、64、128...我将用 p
表示该幂的指数.因此,对于 CHAR_BIT == 8,我们有:
16 == CHAR_BIT * 2 ----> p == 1
32 == CHAR_BIT * 4 ----> p == 2
64 == CHAR_BIT * 8 ----> p == 3
现在我们有:
logarithm(S1) == b == CHAR_BIT * (2 ** p) (I am denoting with ** to the "power math. operator").
logarithm(sqrt(S1)) == logaritm(S1) / 2.0 == CHAR_BIT * (2 ** p) / 2.0 == CHAR_BIT * (2 ** (p - 1))
通过假设或知道 size_t
中的每一位仅用于表示整数的位,我们有这个等式,对于 p
的一些(未知)值:
sizeof(size_t) == b == CHAR_BIT * (2 ** p)
我们可以假设,对于 2014 年的最先进技术,p <= 5
的值,说(你可以在下面将这个神奇的数字 5 增加到更大的值)。
现在,考虑以下表达式,旨在“搜索并找到”b
的值,假设p <= 5
:
#define S_1 ((size_t)1ULL)
#define b (sizeof(size_t))
#define bitexpr(p) ((size_t)(CHAR_BIT * (S_1 << (p))))
#define expr(p) ((size_t) (S_1 << (p)))
#define exp2_expr_1(p) ((size_t)(S_1 << bitexpr(p-1)))
// SRSM() stands for: Square Root SizeMax
#define SRSM ( \
(expr(1)==b)? exp2_expr_1(1) : \
(expr(2)==b)? exp2_expr_1(2) : \
(expr(3)==b)? exp2_expr_1(3) : \
(expr(4)==b)? exp2_expr_1(4) : \
(expr(5)==b)? exp2_expr_1(5) : \
(size_t)0 /* Error! */ \
) /* end-of-macro*/
宏SRSM
实际上,带来了 S+1
的平方根,但我想你可以弄清楚如何处理这个数字。
这里重要的是 SIZE_MAX
的平方根可以通过使用纯整数常量表达式 获得。
如果你愿意,“神奇”的数字 5 可以换成另一个。
一种更通用的方法,旨在解决任意情况,在任何符合标准的可能机器上,它会更复杂。
这篇文章中使用的方法与具有 CHAR_BIT
的值无关, 但它使用字节数是 2 的幂。
已编辑:我稍微更改了“搜索”的方法,从 1 开始,然后逐渐增加,以避免与 <<
可能出现的“错误”匹配。运算符和大数字(一个人永远不知道...)。现在,第一场比赛肯定是正确的。
关于仅使用整数常量表达式计算 sqrt(SIZE_MAX+1),以适应奇怪的 ABI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25625096/
我在玩(美丽的)多项式 x^4 - 10x^2 + 1 . 看看会发生什么: In[46]:= f[x_] := x^4 - 10x^2 + 1 a = Sqrt[2];
对于整个参数范围 x,a >= 0,是否有一种优雅的数值稳定评估以下表达式的方法? f(x,a) = sqrt(x+a) - sqrt(x) 还有没有提供这种功能的任何编程语言或库?如果是,以什么名义
我正在制作自定义运算符 (≠,≈,Σ,√),平方根的实现很有趣。我写的 prefix func √ (item:Double) -> Double { return sqrt(item) }
这是我每秒调用多次的函数: static inline double calculate_scale(double n) { //n may be int or double return s
我对 C++ 很陌生,我有这段代码,代码如下所示: D = (sum_B / double(E))*std::sqrt(E) 有人可以将其解释为数学公式或易于理解的东西吗,我不确定这是什么 std::
这个问题在这里已经有了答案: Can a declaration affect the std namespace? (2 个答案) Why doesn't adding sqrt() cause
考虑以下代码: #include #include const int COUNT = 100000000; int main() { double sum = 0; for (i
x**(1/2)、math.sqrt() 和 cmath.sqrt() 有什么区别? 为什么 cmath.sqrt() 单独得到二次项的复根?我应该专门将它用于我的平方根吗?他们在后台做了什么不同的事
我创建了一个小程序,如下: #include #include #include int main(int argc, char *argv[]) { int i;
我得到了如下表达式(Sqrt[XXX] 的数量未知) Sqrt[A+B] + Sqrt[Min[A,B]] * Min[Sqrt[C],D] 我想把所有的 Sqrt[XXX] 变成 Sqrt(XXX)
这次重复: T(n) = sqrt(n) * T(sqrt(n)) + n 它似乎无法用 Master 定理求解。它似乎也无法用 Akra-Bazzi 解决。即使我设置 n = 2^k 以便 T(2^
在数学中,恒等式 (1 + sqrt(2))^2 = 3 + 2*sqrt(2) 成立。但在浮点(IEEE 754,使用单精度,即 32 位)计算中,情况并非如此,因为 sqrt(2) 没有精确的二进
我创建了一个小程序,如下: #include #include #include int main(int argc, char *argv[]) { int i;
这给了我 0: int B=-4; double A = Math.Sqrt(1/B); 但是这个 NaN double A = Math.Sqrt(-4); 第一次计算怎么可能不失败或者至少不返回
template T sqrt (T); template complex sqrt(complex); double sqrt(double); void f(complex z) { sq
这里是 Python 的新手。我试图了解此函数如何检查素数: from itertools import count, islice from math import sqrt def is_prim
上述复杂性的大 O 表示法是什么? 是不是O(n) 最佳答案 是的。关键是日志里面的平方根没有区别: O(sqrt(n) log(sqrt(n))) = O(sqrt(n) 1/2 log(n)) =
如果 g(n) = sqrt(n)sqrt(n),g(n) = O(2n) 的复杂度是多少? 感谢任何帮助。 最佳答案 比较两个指数函数时,一个有用的技巧是让它们具有相同的基数: √n√n = (2l
我正在查看我的代码,希望提高它的性能,然后我看到了这个: int sqrt = (int) Math.floor(Math.sqrt(n)); 哦,好的,我真的不需要调用 Math.floor,因为转
我试图找到满足子句 (x - y * √ 2016)/(y + √ 2016) = 2016 的数字。数字 x 和 y 可以是有理数。 这是我已经尝试过的: #include #include #
我是一名优秀的程序员,十分优秀!