linq到SQL Math.ROUND问题[英] LINQ to SQL Math.Round Problem

本文是小编为大家收集整理的关于linq到SQL Math.ROUND问题的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我遇到了我编写的查询问题,由于某种原因,我用来在小数点位置后用来存储小数值6个值的变量(它们主要是0).

我尝试了以下(使用Math.Round的不同组合),没有运气.

Sales =
          (from invhed in INVHEAD 
           ... // Joins here
           orderby cust.State ascending
           select new Sale
           {
                InvoiceLine = inv.InvoiceLine,
                InvoiceNum = inv.InvoiceNum,
                ...
                NetPrice = Math.Round((inv.ExtPrice - inv.Discount) * (Decimal) (qsales.RepSplit / 100.0), 2, MidpointRounding.ToEven),
           }).ToList<Sale>();

NetPrice成员具有300.000000、5000.500000、3245.250000等值之类的值

有线索吗?我似乎在网上找不到这个问题.

编辑:

DECIMAL.ROUND做到了​​这一技巧(我忘了提到NetPrice成员是十进制类型).请参阅下面的答案.

推荐答案

我使用decimal.round()的参数与以前相同的参数使它上班. :)

看起来这个问题在某种程度上是在帕维尔所说的踪迹,小数类型的行为不同,而且似乎数学.

感谢所有输入.

其他推荐答案

尾随的零可以出现在小数类型上的.tostring的输出中.您需要在要使用正确格式字符串显示的小数点后指定数字数.例如: -

 var s = dec.ToString("#.00");

显示2个小数位.

内部小数类型使用整数和小数缩放系数.它的缩放系数会导致尾随0.如果您从小数类型开始,比例为2,即使它们是0.

添加和取消小数将导致小数的比例因子为IS IS最大小数的最大小数.因此,从另一个相同的比例系数中减去一个小数为2的小数.

小数的乘法和划分将导致十进制的比例因子,即缩放因子是两个小数操作数的缩放因子的总和.将小数的比例系数为2个,导致一个新十进制的比例因子为4.

.

尝试以下操作: -

var x = new decimal(1.01) - (decimal)0.01;
var y = new decimal(2.02) - (decimal)0.02;
Console.WriteLine(x * y * x * x);

您得到2.00000000.

其他推荐答案

System.Decimal按设计保留尾随的零.换句话说,1m和1.00m是两个不同的decimal s(尽管它们将以相等的比较),并且可以解释为被舍入到不同数量的小数位 - 例如Math.Round(1.001m)将给出1m,Math.Round(1.001m, 2)将给出1.00m.算术运算符对其进行不同的处理 - +和-将产生与具有大多数的操作数相同的位置(SO *),并且*和/将具有相同的位置数量其操作数的位置数量(So 1.00m * 1.000m == 1.00000m).

本文地址:https://www.itbaoku.cn/post/1556758.html

问题描述

I'm having an issue with a query I wrote where for some reason the variable that I'm using to store a decimal value in returns 6 values after the decimal place (they're mostly 0).

I have tried the following (and different combinations using Math.Round) with no luck.

Sales =
          (from invhed in INVHEAD 
           ... // Joins here
           orderby cust.State ascending
           select new Sale
           {
                InvoiceLine = inv.InvoiceLine,
                InvoiceNum = inv.InvoiceNum,
                ...
                NetPrice = Math.Round((inv.ExtPrice - inv.Discount) * (Decimal) (qsales.RepSplit / 100.0), 2, MidpointRounding.ToEven),
           }).ToList<Sale>();

The NetPrice member has values like 300.000000, 5000.500000, 3245.250000, etc.

Any clues? I can't seem to find anything on this issue online.

EDIT:

Decimal.Round did the trick (I forgot to mention that the NetPrice member was a Decimal type). See my answer below.

推荐答案

I got it to work using Decimal.Round() with the same arguments as before. :)

Looks like the issue is somewhat on the trail of what Pavel was saying, where Decimal types behave differently and it would seem Math.Round doesn't quite work with them as one would expect it to...

Thanks for all the input.

其他推荐答案

Trailing zeros can appear in the output of .ToString on the decimal type. You need to specify the number of digits after the decimal point you want display using the correct format string. For example:-

 var s = dec.ToString("#.00");

display 2 decimal places.

Internally the decimal type uses an integer and a decimal scaling factor. Its the scaling factor which gives rise to the trailing 0. If you start off with a decimal type with a scaling factor of 2, you will get 2 digits after the decimal point even if they are 0.

Adding and substracting decimals will result in a decimal which has a scaling factor of the is the maximum of the decimals involved. Hence subtracting one decimal with a scaling factor of 2 from another with the same the resulting decimal also has a factor of 2.

Multiplication and division of decimals will result in a decimal that has a scaling factor that is the sum of the scaling factors of the two decimal operands. Multiplying decimals with a scaling factor of 2 results in a new decimal that has a scaling factor of 4.

Try this:-

var x = new decimal(1.01) - (decimal)0.01;
var y = new decimal(2.02) - (decimal)0.02;
Console.WriteLine(x * y * x * x);

You get 2.00000000.

其他推荐答案

System.Decimal preserves trailing zeroes by design. In other words, 1m and 1.00m are two different decimals (though they will compare as equal), and can be interpreted as being rounded to different number of decimal places - e.g. Math.Round(1.001m) will give 1m, and Math.Round(1.001m, 2) will give 1.00m. Arithmetic operators treat them differently - + and - will produce a result that has the the same number of places as the operand which has most of them (so 1.50m + 0.5m == 1.10m), and * and / will have the sum of number of places for their operands (so 1.00m * 1.000m == 1.00000m).