为什么Python会给出"错误"的答案?
x = 16
sqrt = x**(.5)
returns 4
sqrt = x**(1/2)
returns 1
Run Code Online (Sandbox Code Playgroud)
是的,我知道import math
并使用sqrt
.但我正在寻找上述答案.
这只是为了满足我自己的好奇心。
是否有此实现:
float InvSqrt (float x)
{
float xhalf = 0.5f*x;
int i = *(int*)&x;
i = 0x5f3759df - (i>>1);
x = *(float*)&i;
x = x*(1.5f - xhalf*x*x);
return x;
}
Run Code Online (Sandbox Code Playgroud)
在Rust中?如果存在,则发布代码。
我尝试过但失败了。我不知道如何使用整数格式编码浮点数。这是我的尝试:
fn main() {
println!("Hello, world!");
println!("sqrt1: {}, ",sqrt2(100f64));
}
fn sqrt1(x: f64) -> f64 {
x.sqrt()
}
fn sqrt2(x: f64) -> f64 {
let mut x = x;
let xhalf = 0.5*x;
let mut i = x as i64;
println!("sqrt1: {}, ", i);
i = 0x5f375a86 as …
Run Code Online (Sandbox Code Playgroud) 我需要计算一些数字的平方根,例如\xe2\x88\x9a9 = 3
和\xe2\x88\x9a2 = 1.4142
。我怎样才能用Python做到这一点?
输入可能都是正整数,并且相对较小(比如小于十亿),但万一它们不是,有什么可能会破坏吗?
\n注意:这是在 Meta 上讨论现有同标题问题后对规范问题的尝试。
\n有关的
\n在python或标准库中是否存在整数平方根?我希望它是准确的(即返回一个整数),并且如果没有解决方案则吠叫.
目前我推出了自己的天真的:
def isqrt(n):
i = int(math.sqrt(n) + 0.5)
if i**2 == n:
return i
raise ValueError('input was not a perfect square')
Run Code Online (Sandbox Code Playgroud)
但它很难看,我不相信大整数.如果我超过了这个值,我可以遍历正方形并放弃,但我认为做这样的事情会有点慢.另外我想我可能正在重新发明轮子,这样的东西肯定已经存在于python ......
作为我编写的程序的一部分,我需要比较形式为a + sqrt(b)
where a
和b
unsigned integer的两个值。由于这是紧密循环的一部分,因此我希望此比较尽可能快地运行。(如果重要的话,我正在x86-64机器上运行代码,并且无符号整数不大于10 ^ 6。此外,我知道这样的事实a1<a2
。)
作为独立功能,这就是我要优化的功能。我的数字是足够小的整数,可以double
(或什至float
)精确地表示它们,但是sqrt
结果中的舍入误差不能改变结果。
// known pre-condition: a1 < a2 in case that helps
bool is_smaller(unsigned a1, unsigned b1, unsigned a2, unsigned b2) {
return a1+sqrt(b1) < a2+sqrt(b2); // computed mathematically exactly
}
Run Code Online (Sandbox Code Playgroud)
测试用例:is_smaller(900000, 1000000, 900001, 998002)
应返回true,但如@wim注释所示,sqrtf()
将其返回false。因此将(int)sqrt()
截断为整数。
a1+sqrt(b1) = 90100
和a2+sqrt(b2) = 901000.00050050037512481206
。最接近的浮点数就是90100。
由于sqrt()
即使在现代的x86-64上作为sqrtsd
指令完全内联时,该函数通常也非常昂贵,所以我试图避免sqrt()
尽可能地调用。
通过平方运算删除sqrt还可以通过使所有计算都精确来避免舍入错误的任何危险。
如果相反,功能是这样的...
bool is_smaller(unsigned …
Run Code Online (Sandbox Code Playgroud) 我需要快速的整数平方根,不涉及任何明确的除法.目标RISC架构可以在一个周期内执行add,mul,sub,shift等操作(好的 - 操作的结果是在第三个周期写的,真的 - 但是有交错),所以任何使用这些操作并且速度很快的Integer算法都会非常赞赏.
这就是我现在所拥有的,我认为二进制搜索应该更快,因为以下循环每次执行16次(无论值如何).我还没有广泛地调试它(但很快),所以也许有可能提前退出:
unsigned short int int_sqrt32(unsigned int x)
{
unsigned short int res=0;
unsigned short int add= 0x8000;
int i;
for(i=0;i<16;i++)
{
unsigned short int temp=res | add;
unsigned int g2=temp*temp;
if (x>=g2)
{
res=temp;
}
add>>=1;
}
return res;
}
Run Code Online (Sandbox Code Playgroud)
看起来上面[在目标RISC的上下文中]的当前性能成本是5个指令的循环(bitset,mul,compare,store,shift).缓存中可能没有完全展开的空间(但这将是部分展开的主要候选者[例如,4循环而不是16],当然).因此,成本是16*5 = 80指令(加上循环开销,如果没有展开).如果完全交错,则仅花费80(对于最后指令为+2)周期.
我可以在82个周期内获得一些其他sqrt实现(仅使用add,mul,bitshift,store/cmp)吗?
常问问题:
为什么不依靠编译器来生成一个好的快速代码?
该平台没有可用的C-> RISC编译器.我将把当前的参考C代码移植到手写的RISC ASM中.
您是否对代码进行了分析,以确定它add
是否真的成为瓶颈?
不,没有必要.目标RISC芯片大约为20 MHz,因此每条指令都很重要.核心环(计算射击器和接收器贴片之间的能量转移形状因子),mul
使用它,将在每个渲染帧运行~1000次(当然,假设它足够快),每秒高达60,000,整个演示大约有1,000,000次.
您是否尝试过优化算法以删除sub
?
是的,我已经这样做了.事实上,我已经摆脱了2 shift
秒和许多分裂(移除或替换为移位).即使在我的千兆赫笔记本上,我也可以看到巨大的性能提升(与参考浮动版相比).
申请是什么?
它是compo演示的实时渐进细化光能传递渲染器.我们的想法是每帧都有一个拍摄周期,所以它会在每个渲染帧上明显地收敛并且看起来更好(例如每秒上升60次,尽管SW光栅化器可能不会那么快[但至少它可以运行]在与RISC并行的另一个芯片上 - 因此,如果渲染场景需要2-3帧,RISC将并行处理2-3帧的光能传递数据.).
为什么不直接在目标ASM中工作?
因为光能传递是一个略微涉及的算法,我需要Visual Studio的即时编辑和继续调试功能.我周末在VS中做了几百次代码更改,将浮点数学转换为整数,这将花费我6个月的目标平台,只打印"调试".
你为什么不能使用分裂?
因为它在目标RISC上的速度比以下任何一个慢16倍:mul,add,sub,shift,compare,load/store(只需1个周期).因此,它仅在绝对需要时才使用(不幸的是,已经好几次,当不能使用换档时). …
我想看看Python计算平方根的方式,所以我试图找到它的定义math.sqrt()
,但我无法在任何地方找到它.我看过的_math.c
,mathmodule.c
和其他地方.
我知道python使用C的数学函数,但它们是在Python发行版中的某个地方,还是在其他地方链接到代码?我使用的是Mac OS X.
算法在math.sqrt()
哪里?
我发现了不使用sqrt函数找出平方根的算法,然后尝试进入编程.我最终使用C++中的这个工作代码
#include <iostream>
using namespace std;
double SqrtNumber(double num)
{
double lower_bound=0;
double upper_bound=num;
double temp=0; /* ek edited this line */
int nCount = 50;
while(nCount != 0)
{
temp=(lower_bound+upper_bound)/2;
if(temp*temp==num)
{
return temp;
}
else if(temp*temp > num)
{
upper_bound = temp;
}
else
{
lower_bound = temp;
}
nCount--;
}
return temp;
}
int main()
{
double num;
cout<<"Enter the number\n";
cin>>num;
if(num < 0)
{
cout<<"Error: Negative number!";
return 0;
}
cout<<"Square roots are: +"<<sqrtnum(num) and …
Run Code Online (Sandbox Code Playgroud)