【问题标题】:Discrepancy in computations计算差异
【发布时间】:2016-06-14 21:22:36
【问题描述】:
SET QUOTED_IDENTIFIER ON
GO

ALTER FUNCTION [dbo].[fn_LensThickCalcAC] (@sph as DECIMAL(9,2),
                              @cyl as DECIMAL(9,2),
                              @ri as DECIMAL(9,2),
                              @bc as DECIMAL(9,2), 
                              @dia as SMALLINT,
                              @ct as DECIMAL(9,2),
                              @axs as SMALLINT)
RETURNS FLOAT
AS 
BEGIN 

DECLARE @dR2S DECIMAL(9,2)
DECLARE @dR2SC DECIMAL(9,2)
DECLARE @dSizeA DECIMAL(9,2)
DECLARE @dSizeB DECIMAL(9,2)
DECLARE @dSizeC DECIMAL(9,2)
DECLARE @dSizeB_S FLOAT
DECLARE @dSizeB_SC FLOAT
DECLARE @dThickness DECIMAL(9,2)
DECLARE @dAxs DECIMAL(9,2)

DECLARE  @dESizeB_S FLOAT
DECLARE  @dESizeB_SC FLOAT
DECLARE  @dDiffSC FLOAT

DECLARE @dR1 DECIMAL(9,2)
DECLARE @dESizeD FLOAT
DECLARE @dSizeD DECIMAL(9,2)
DECLARE @adjThick DECIMAL(9,2)
DECLARE @finalThick DECIMAL(9,2)

IF(@AXS > 0) 
   BEGIN
    IF (@AXS >= 180)
       BEGIN 
         SET @dAxs = @AXS - 90
       END
    ELSE 
       BEGIN 
         SET @dAxs = @AXS
       END 
    END
ELSE
   BEGIN 
     SET @dAxs = @AXS
   END 

SET @dR2S = ((@RI - 1.0) * 1000) / (@BC - @Sph)


SET @dDiffSC = @BC - (@Sph + @Cyl)

IF @dDiffSC = 0 
  BEGIN 
    SET @dDiffSC = @BC
  END 

SET @dR2SC = ((@RI - 1.0) * 1000) / (@dDiffSC)

SET @dESizeB_S = POWER(@dR2S,2) - POWER(@DIA /2,2)
SET @dESizeB_SC = POWER(@dR2SC,2) - POWER(@DIA /2,2)

SET @dSizeB_S = @dR2S - Sqrt(@dESizeB_S)
SET @dSizeB_SC = @dR2SC - Sqrt(@dESizeB_SC)
SET @dSizeA = @CT

IF @dSizeB_S > @dSizeB_SC
   BEGIN 
     SET @dSizeB = @dSizeB_S
   END 
ELSE 
   BEGIN 
     SET @dSizeB = @dSizeB_SC
   END 

SET @dSizeC = @dSizeA + @dSizeB

SET @dR1 = (@RI - 1.0) * 1000 / (@BC)
SET @dESizeD = POWER(@dR1,2) - POWER(@DIA /2,2)

IF @dR1 > @dR2S
    BEGIN
        SET @dSizeD = @dR1 - sqrt(@dESizeD)
    END
ELSE
    BEGIN
        SET @dSizeD = @dSizeB
    END

SET @adjThick = @dSizeC - @dSizeD

IF @dSizeD > 3.50
    BEGIN
        SET @dSizeD = @dSizeD - 3.50
        SET @finalThick = @adjThick + @dSizeD + 1.50
    END
ELSE
    BEGIN
        SET @finalThick =  @adjThick + 1.50
    END

RETURN @finalThick

END

从上面存储的 SQL 函数中,尝试从中派生一个简单的 C# 应用程序。

产品:

public float calc2(decimal sph, decimal cyl, decimal bc, decimal dia, decimal ct, decimal Axs)
        {

        decimal ri = 1.74M, dAxis, dR2S, dR2SC, dR1;
        decimal dDiffSC, dSizeB_S, dSizeB_SC, dESizeD, dESizeB_S, dESizeB_SC;
        decimal dSizeA, dSizeB, dSizeC, dSizeD;
        decimal adjthick;
        float finaloutput;
        dAxis = Axs > 0 ? (Axs >= 180 ? Math.Round(Axs - 90,2) : Math.Round(Axs,2)) : Math.Round(Axs,2);

        dR2S = Math.Round((((Math.Round(ri, 2) - 1.0M) * 1000)/(bc - sph)),2);

        dDiffSC = bc - (sph + cyl);
        dDiffSC = dDiffSC == 0 ? bc : dDiffSC;

        dR2SC = Math.Round((((Math.Round(ri, 2) - 1.0M) * 1000) / (dDiffSC)),2);

        dESizeB_S = dPow(dR2S, 2M) - dPow((dia/2), 2M);
        dESizeB_SC = dPow(dR2SC, 2M) - dPow((dia/2), 2M);

        dSizeB_S = dR2S - (decimal)Math.Sqrt((double)dESizeB_S);
        dSizeB_SC = dR2SC - (decimal)Math.Sqrt((double)dESizeB_SC);
        dSizeA = Math.Round(ct, 2);

        dSizeB = dSizeB_S > dSizeB_SC ? Math.Round(dSizeB_S,2) : Math.Round(dSizeB_SC,2);

        dSizeC = Math.Round((dSizeA + dSizeB),2);

        dR1 = Math.Round((((Math.Round(ri, 2) - 1.0M) * 1000) / (bc)),2);
        dESizeD = dPow(dR1, 2M) - dPow((dia/2), 2M);

        dSizeD = dR1 > dR2S ? Math.Round((dR1 - (decimal)Math.Sqrt((double)dESizeD)),2): Math.Round(dSizeB,2);

        adjthick = Math.Round((dSizeC - dSizeD),2);

        finaloutput = dSizeD > 3.50M ? (float)Math.Round((adjthick + (dSizeD - 3.50M) + 1.50M),2) : (float)Math.Round((adjthick + 1.50M),2);
        return finaloutput;
    }

    public static decimal dPow(decimal x, decimal y)
    {
        Double X = (double)x;
        Double Y = (double)y;
        return (decimal)System.Math.Pow(X, Y);
    }

但是,在更改数据类型(double、decimal、float 等)方面经过数小时的反复试验。我仍然有差异。

使用这些值:

  1. sph = -2.00
  2. 圆柱 = 0.00
  3. ri = 1.74
  4. 公元前 = 1.00
  5. 直径 = 75
  6. ct = 1.10
  7. 轴 = 180

在 SQL 中执行存储函数后。
我得到了 4.46
的结果 在 C# 中运行我的代码后。
我得到了 4.52

的结果

这是一个小的差异,但随着sphcyl的变化,这两种方法产生的差异也会增加。

问题:
我使用的数据类型有问题吗?
SQL Server 的行为是否与 C# 不同?
这些差异还有其他可能的因素吗?

【问题讨论】:

  • 有一种简单的方法可以找出差异的开始位置。将两个程序简化为只运行第一个计算。他们给出相同的结果吗?如果没有,你就完成了。你发现了不同之处。如果是,请添加另一行。重复直到你得到一条给出不同结果的行。这就是错误所在。
  • @EricLippert 我可以在 C# 中轻松做到这一点,但在 SQL Server 中是另一回事。
  • 这个问题可能也有用stackoverflow.com/questions/3152439/…
  • 您可能想要检查您正在使用的大量隐式转换和常量。手工计算也可以帮助您了解问题所在:)
  • @LesH 好的,我会检查一下。

标签: c# sql-server computation


【解决方案1】:

更新:知道了。我需要将 diaaxs 的数据类型更改为 SMALLINT / Int16 谢谢您的帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-25
    • 1970-01-01
    • 2013-07-10
    • 2011-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多