【问题标题】:C# Math.Round and nullable DoublesC# Math.Round 和可为空的双精度数
【发布时间】:2012-11-30 21:14:30
【问题描述】:

我承担了将一个非常古老的经典 ASP/VBScript/Access 网站转换为“当前”网站的任务。正如您所怀疑的那样,大部分操作都更容易重做,但是有一个报告页面依赖于一堆没有记录的计算,所以我只需要使用他的代码/公式,但将它们移动到 C# .

为了全面披露,我将 Access 数据库导入 SQL Server 没有任何问题。我使用 EntityFramewok PowerTools(代码优先)对新数据库进行逆向工程并创建我的 .edmx 文件。我注意到,当 EntityFramework 为我创建 .edmx 时,它在 C# 类中将数据库中浮动的字段定义为可为空的 Doubles(Double?)...是否存在任何转置、截断或更改值的风险将float转换为可为空的double时的方式?

我认为值得怀疑的另一个地方是四舍五入。显然,四舍五入的数学并没有改变,但我想知道 VBScript 和 C# 在如何四舍五入方面是否有任何已知差异。

VBScript 中的这些行

varA1=oDataRs("boundData")
varB1i=varA1*3.0689
varB1=round(varB1i,3)

变成了C#

var newVal = Math.Round(boundData.Value * 3.0689,3);

我没有将任何内容转换为双精度或十进制,只是在它从数据库中出来时使用它。我必须使用 .Value ,否则我不能乘以 Double ?还有一个 Double。

这些值非常接近,但在一条非常重要的数据上相差约 0.036,我找不到任何原因。

【问题讨论】:

    标签: c# sql ms-access vbscript


    【解决方案1】:

    事实上,both .NETVB use the Banker's Rounding algorithm,所以只要不指定 MidpointRounding.AwayFromZero 就应该得到一致的结果。

    真正有趣的问题是 Access 数据库中的源数据是浮点数还是货币列。如果是货币,那么您应该使用小数,而不是双精度。如果被倍增的数字的大小有足够的不同,这可能会导致微小的差异。

    对于特别重要的数据,boundData的值是多少?

    【讨论】:

    • 感谢您提供的信息!我检查了原始的 Access 电子表格,它们存储为数据类型“数字”。在我发布的示例之前和之后都有大量代码,但就检索和舍入而言,它们都与示例相似。 BoundData 是从 0.001 到 9.999 的任意值,它们都不是货币值。
    • 在 Access 表设计视图中,“数字”更多是一种数据类型 category。进一步向下查看“字段属性”部分的“常规”选项卡。在“Field Size”选择框中找到具体的类型(Byte、Integer、Long Integer、Single、Double等)。
    • 感谢 HansUp。它们实际上是 Double,Required 设置为 No。所以我猜 Nullable Double 是有道理的;)
    • 我想我是在要求复制。你是否将 0.001 乘以你的常数,当你四舍五入时,你得到 0.004?错误案例的输入值、预期结果和实际结果是什么?例如,对于 9.999,我希望我的结果是 30.686。
    • Rob & @HansUp - 感谢您对此的帮助。原来我在两个数据源之间有一些不匹配的数据,这与我走的路无关。无论如何,我将其标记为答案,因为它是我问题的绝佳答案。
    猜你喜欢
    • 2016-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-13
    • 2015-05-17
    相关资源
    最近更新 更多