Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在sqlite中计算平方根_Sql_Sqlite_Math - Fatal编程技术网

如何在sqlite中计算平方根

如何在sqlite中计算平方根,sql,sqlite,math,Sql,Sqlite,Math,我需要在sqlite数据库中计算欧几里德距离 除了编写和加载数学函数的动态库之外,还有人知道如何在sqlite中计算平方根吗 在这里,我接近于求助于快速平方根逆算法,尽管它可能会变得比我现在需要的更有趣 作为旁注,弄清楚如何计算幂(这是一个广义的问题,编码比数字本身相乘更简洁)会很好 谢谢 西蒙妮嗯,我有一个半答案 是的,它涉及第三方,但您不必自己编写:您是否检查了上一个扩展 它包括几个数学函数,其中包括sqrt()。据我所知,仅使用核心函数是无法做到这一点的 下面是本机函数列表和聚合函数列表

我需要在sqlite数据库中计算欧几里德距离

除了编写和加载数学函数的动态库之外,还有人知道如何在sqlite中计算平方根吗

在这里,我接近于求助于快速平方根逆算法,尽管它可能会变得比我现在需要的更有趣

作为旁注,弄清楚如何计算幂(这是一个广义的问题,编码比数字本身相乘更简洁)会很好

谢谢


西蒙妮

嗯,我有一个半答案

是的,它涉及第三方,但您不必自己编写:您是否检查了上一个扩展


它包括几个数学函数,其中包括sqrt()。

据我所知,仅使用核心函数是无法做到这一点的

下面是本机函数列表和聚合函数列表


要解决您的问题,您可以编写自己的UDF(用户定义函数),如图所示。警告:此答案取决于编码语言。在我的例子中,C#

用户定义的SQLite函数对我来说是一个难以实现的难题。最后,经过长时间的搜索,我能够在我的C#代码中实现它。主要功能如下所示:

[SQLiteFunction(Arguments = 1, FuncType = FunctionType.Scalar, Name = "Sqrt")]
class Sqrt : SQLiteFunction
{
    public override object Invoke(object[] args)
    {
        return Math.Sqrt(Double.Parse(args[0].ToString()));
    }
}
自定义功能的注册:

SQLiteFunction.RegisterFunction(typeof(Sqrt));
并在选择中使用:

SQLiteCommand com = new SQLiteCommand("select sqrt(10.42)", connection);
您可以在此处下载完整示例:

或者,如果您只想查看代码(或者浏览代码的所有部分),我将在下面粘贴SQLite数据库中计算平方根的完整工作示例代码,因为很难找到任何适用于此的工作代码。要创建并运行此示例,请执行以下6个步骤:

  • 创建新项目(我的名字是Sqrt)
  • 将SQLite引用包括到项目中:
    解决方案资源管理器->引用(右键单击:添加引用)->程序集-扩展-System.Data.SQLite(检查)->确定
  • 打开App.config并替换为此(如果不执行此步骤,可能会出现混合模式程序集错误):






  • 将Form1.Designer.cs替换为以下代码:

    namespace Sqrt
    {
     partial class Form1
     {
     /// <summary>
     /// Required designer variable.
     /// </summary>
     private System.ComponentModel.IContainer components = null;
    
     /// <summary>
     /// Clean up any resources being used.
     /// </summary>
     /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
     protected override void Dispose(bool disposing)
     {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
     }
    
     #region Windows Form Designer generated code
    
     /// <summary>
     /// Required method for Designer support - do not modify
     /// the contents of this method with the code editor.
     /// </summary>
     private void InitializeComponent()
     {
        this.txb_Input = new System.Windows.Forms.TextBox();
        this.txb_Output = new System.Windows.Forms.TextBox();
        this.label1 = new System.Windows.Forms.Label();
        this.label2 = new System.Windows.Forms.Label();
        this.btn_Calcualte = new System.Windows.Forms.Button();
        this.SuspendLayout();
        // 
        // txb_Input
        // 
        this.txb_Input.Location = new System.Drawing.Point(131, 12);
        this.txb_Input.Name = "txb_Input";
        this.txb_Input.Size = new System.Drawing.Size(201, 20);
        this.txb_Input.TabIndex = 0;
        // 
        // txb_Output
        // 
        this.txb_Output.BackColor = System.Drawing.Color.WhiteSmoke;
        this.txb_Output.Location = new System.Drawing.Point(131, 38);
        this.txb_Output.Name = "txb_Output";
        this.txb_Output.ReadOnly = true;
        this.txb_Output.Size = new System.Drawing.Size(201, 20);
        this.txb_Output.TabIndex = 0;
        // 
        // label1
        // 
        this.label1.AutoSize = true;
        this.label1.Location = new System.Drawing.Point(12, 15);
        this.label1.Name = "label1";
        this.label1.Size = new System.Drawing.Size(31, 13);
        this.label1.TabIndex = 1;
        this.label1.Text = "Input";
        // 
        // label2
        // 
        this.label2.AutoSize = true;
        this.label2.Location = new System.Drawing.Point(12, 41);
        this.label2.Name = "label2";
        this.label2.Size = new System.Drawing.Size(39, 13);
        this.label2.TabIndex = 1;
        this.label2.Text = "Output";
        // 
        // btn_Calcualte
        // 
        this.btn_Calcualte.Location = new System.Drawing.Point(257, 64);
        this.btn_Calcualte.Name = "btn_Calcualte";
        this.btn_Calcualte.Size = new System.Drawing.Size(75, 23);
        this.btn_Calcualte.TabIndex = 2;
        this.btn_Calcualte.Text = "Calculate";
        this.btn_Calcualte.UseVisualStyleBackColor = true;
        // 
        // Form1
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(344, 98);
        this.Controls.Add(this.btn_Calcualte);
        this.Controls.Add(this.label2);
        this.Controls.Add(this.label1);
        this.Controls.Add(this.txb_Output);
        this.Controls.Add(this.txb_Input);
        this.Name = "Form1";
        this.Text = "Root square example";
        this.ResumeLayout(false);
        this.PerformLayout();
     }
     #endregion
    
     private System.Windows.Forms.TextBox txb_Input;
     private System.Windows.Forms.TextBox txb_Output;
     private System.Windows.Forms.Label label1;
     private System.Windows.Forms.Label label2;
     private System.Windows.Forms.Button btn_Calcualte;
     }
    }
    
  • 跑,试着享受


  • 对于10000以下的数字,这是sqrt的近似值。它可以扩展到任意数字,也可以根据需要扩展到任意精度。无论如何,这种表格插值在大多数快速实现中都会发生:

    case when weight >= 1 and weight<=10 then 1+0.240253073*(weight-1) 
         when weight>=10 and weight<=100 then 3.16227766+0.075974693*(weight-10) 
         when weight>=100 and weight<=1000 then 10+0.024025307*(weight-100)      
         else 31.6227766+0.007597469 *(weight-1000) end
    
    一个比我更好的数学头脑可能会得出更好更密集的近似值。考虑到c中的大多数sqrt函数都使用近似-这是一个非常好的解决方案

    这是唯一一种土生土长的方法

    添加了内置的SQL数学函数()。(需要-DSQLITE\u ENABLE\u MATH\u FUNCTIONS编译时选项。)

    sqrt(X)返回X的平方根。如果X为负,则返回NULL


    仅当数学函数不可用时。。。真的只有在绝望中,因为这不会很快

    -- bisect to find the square root to any tolerance desired
    with 
     input(n) as (select 500), --input
     sqrt(lo, hi, guess, n, i) as (
      select 1, n, n/2, n, 0 from input
      union all
      select case when guess*guess < n then guess else lo end,
             case when guess*guess < n then hi else guess end,
             case when guess*guess < n then (hi+guess)/2.0 else (lo+guess)/2.0 end,
             n ,
             i +1 from sqrt
             where abs(guess*guess - n) > 0.0001), -- tolerance
     sqrt_out(x, n) as (select guess, n from sqrt order by sqrt.i desc limit 1)
     select * from sqrt_out
    
    --对分以找到任意所需公差的平方根
    具有
    输入(n)为(选择500),--输入
    sqrt(lo,hi,guess,n,i)作为(
    从输入中选择1,n,n/2,n,0
    联合所有
    当guess*guess0.0001),--公差
    sqrt_out(x,n)as(按sqrt.i说明限制1从sqrt顺序中选择猜测,n)
    从sqrt\U out中选择*
    
    它必须精确到什么程度?请使用。是一个线索。当比较欧几里德距离时,你可以将两边都平方,而不是平方根-电源看起来可能更干净,但通常速度比日志慢,尽管还有其他方式实现集成电源,我认为SQLite也不支持电源。本机SQLite确实不支持电源。我实际上想要的是避免使用扩展名。然而,我很感激你的回答促使我尝试它——结果比我想象的要容易,现在我知道如何解决下一个类似的问题。感谢如果
    weight
    为9,则表达式的结果为2.922,如果
    weight
    为16,则结果为3.618,我希望接近3和4。你能解释一下你的公式和错误程度吗。弹出打开excel工作表,2。计算平方根,和3。对一组任意权重进行线性插值。上面的穹窿非常近似。如果这部分
    Double.Parse(args[0].ToString())
    处理错误类型的值,您可以做得更好?
     ((length(x)+length(x*2)+length(x*3)
      +length(x*4)+length(x*5))/5.0)-1.0
    
    -- bisect to find the square root to any tolerance desired
    with 
     input(n) as (select 500), --input
     sqrt(lo, hi, guess, n, i) as (
      select 1, n, n/2, n, 0 from input
      union all
      select case when guess*guess < n then guess else lo end,
             case when guess*guess < n then hi else guess end,
             case when guess*guess < n then (hi+guess)/2.0 else (lo+guess)/2.0 end,
             n ,
             i +1 from sqrt
             where abs(guess*guess - n) > 0.0001), -- tolerance
     sqrt_out(x, n) as (select guess, n from sqrt order by sqrt.i desc limit 1)
     select * from sqrt_out