C# Math.Round 和可为 null 的双精度数

问题描述 投票:0回答:1

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

为了充分披露,我将 Access 数据库导入到 SQL Server,没有任何问题。我使用 EntityFramewok PowerTools(Code First)对新数据库进行逆向工程并创建 .edmx 文件。我注意到,当 EntityFramework 为我创建 .edmx 时,它将数据库中的浮点字段定义为 C# 类中的可空双精度数(双精度数?)...是否存在转置、砍伐或更改任何值中的值的风险将 float 转换为可为 null 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 ?和一个双人。

这些值非常接近,但在一个非常重要的数据上偏离了大约 0.036,我找不到任何原因。

c# sql ms-access vbscript
1个回答
6
投票

事实上,.NETVB都使用银行家舍入算法,因此只要不指定 MidpointRounding.AwayFromZero,您就应该获得一致的结果。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.