- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
我想知道这是不是真的:当我对一个平方整数求平方根时,就像在
f = Math.sqrt(123*123)
我将得到一个非常接近 123
的 float 。由于浮点表示精度,这可能类似于 122.99999999999999999999 或 123.000000000000000000001。
因为 floor(122.999999999999999999)
是 122,我应该得到 122 而不是 123。所以我希望 floor(sqrt(i*i)) == i-1
在大约 50% 的情况下。奇怪的是,对于我测试过的所有数字,floor(sqrt(i*i) == i
。这是一个用于测试前 1 亿个数字的小 ruby 脚本:
100_000_000.times do |i|
puts i if Math.sqrt(i*i).floor != i
end
上面的脚本从不打印任何东西。为什么?
更新:感谢您的快速回复,这似乎是解决方案:根据 wikipedia
Any integer with absolute value less than or equal to 2^24 can be exactly represented in the single precision format, and any integer with absolute value less than or equal to 2^53 can be exactly represented in the double precision format.
Math.sqrt(i*i) 从 i=9007199254740993 开始按照我的预期运行,即 2^53 + 1。
最佳答案
这是你困惑的本质:
Due to floating point representation precision, this could be something like 122.99999999999999999999 or 123.000000000000000000001.
这是错误的。在符合 IEEE-754 标准的系统上,它总是恰好是 123,这几乎是现代的所有系统。浮点运算没有“随机误差”或“噪声”。它具有精确的、确定性的舍入,许多简单的计算(比如这个)根本不会产生任何舍入。
123
可以精确表示为 float ,123*123
也是如此(所有 中等大小的整数也是如此)。因此当您将 123*123
转换为浮点类型时不会发生舍入错误。结果完全 15129
。
根据 IEEE-754 标准,平方根是正确舍入的运算。这意味着如果有一个确切的答案,则需要平方根函数来产生它。由于您要对 exactly 15129
求平方根,即 exactly 123
,因此 exactly 从平方根函数得到的结果。不进行舍入或近似。
现在,对于多大的整数,这将是正确的?
double 可以准确表示 2^53 以内的所有整数。因此,只要 i*i
小于 2^53,您的计算中就不会发生舍入,因此结果将是准确的。这意味着对于所有小于 94906265
的 i
,我们知道计算是准确的。
但是你试过 i
比那个大!发生了什么事?
对于您尝试过的最大 i
,i*i
仅略大于 2^53 (1.1102... * 2^53
,实际上)。因为从整数到 double 的转换(或 double 乘法)也是正确舍入操作,i*i
将是最接近 i 精确平方的可表示值
。在这种情况下,由于 i*i
是 54 位宽,舍入将发生在最低位。因此我们知道:
i*i as a double = the exact value of i*i + rounding
其中 rounding
是 -1,0 或 1
。如果四舍五入为零,则平方是精确的,因此平方根是精确的,所以我们已经知道您得到了正确答案。让我们忽略这种情况。
现在我们要计算 i*i +/- 1
的平方根。使用泰勒级数展开,此平方根的无限精确(未四舍五入)值为:
i * (1 +/- 1/(2i^2) + O(1/i^4))
如果你以前没有做过任何浮点错误分析,现在这有点繁琐,但如果你使用 i^2 > 2^53
这个事实,你可以看到的:
1/(2i^2) + O(1/i^4)
term 小于 2^-54,这意味着(因为平方根被正确舍入,因此它的舍入误差必须小于 2^54),舍入 sqrt 的结果函数正是 i
。
事实证明(通过类似的分析),对于任何可精确表示的 float x,sqrt(x*x) 正好是 x(假设 x*x
的中间计算没有不会溢出或下溢),因此您遇到此类计算舍入的唯一方法是在 x
本身的表示中,这就是为什么您看到它从 2^53 开始+ 1
(不可表示的最小整数)。
关于ruby - 为什么 Math.sqrt(i*i).floor == i?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2060486/
我在玩(美丽的)多项式 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 #
我是一名优秀的程序员,十分优秀!