截去小数点后两位,不四舍五入
假设我的值为 3.4679,想要 3.46,如何将其截断到小数点后两位而不向上舍入?
我尝试了以下方法,但所有三个都给了我 3.47:
void Main()
{
Console.Write(Math.Round(3.4679, 2,MidpointRounding.ToEven));
Console.Write(Math.Round(3.4679, 2,MidpointRounding.AwayFromZero));
Console.Write(Math.Round(3.4679, 2));
}
这返回 3.46,但看起来有点脏:
void Main()
{
Console.Write(Math.Round(3.46799999999 -.005 , 2));
}
Lets say I have a value of 3.4679 and want 3.46, how can I truncate that to two decimal places without rounding up?
I have tried the following but all three give me 3.47:
void Main()
{
Console.Write(Math.Round(3.4679, 2,MidpointRounding.ToEven));
Console.Write(Math.Round(3.4679, 2,MidpointRounding.AwayFromZero));
Console.Write(Math.Round(3.4679, 2));
}
This returns 3.46, but just seems dirty some how:
void Main()
{
Console.Write(Math.Round(3.46799999999 -.005 , 2));
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(25)
请注意,像这样的分数无法用浮点精确表示。
Beware that fractions like these cannot be accurately represented in floating point.
System.Decimal
的通用且快速的方法(没有Math.Pow()
/ 乘法):Universal and fast method (without
Math.Pow()
/ multiplication) forSystem.Decimal
:在 C# 中拥有一个用于实际使用截断小数的完整函数会更有用。如果您愿意,这可以很容易地转换为十进制扩展方法:
如果您需要 VB.NET 尝试这个:
然后像这样使用它:
或
It would be more useful to have a full function for real-world usage of truncating a decimal in C#. This could be converted to a Decimal extension method pretty easy if you wanted:
If you need VB.NET try this:
Then use it like so:
or
使用模运算符:
结果:0.54
Use the modulus operator:
result: 0.54
其他示例的一个问题是它们先将输入值相乘,然后再除以它。这里有一个边缘情况,你可以通过先相乘来溢出小数,这是一个边缘情况,但我遇到过。单独处理小数部分会更安全,如下所示:
One issue with the other examples is they multiply the input value before dividing it. There is an edge case here that you can overflow decimal by multiplying first, an edge case, but something I have come across. It's safer to deal with the fractional part separately as follows:
在 .NET Core 3.0 及更高版本中,
Math.Round
和Decimal.Round
可以通过新的 MidpointRounding.ToZero。对于正数,MidpointRounding.ToNegativeInfinity
具有相同的效果,而对于负数,等效的效果是MidpointRounding.ToPositiveInfinity
。这些生产线:
生产:
In .NET Core 3.0 and later
Math.Round
andDecimal.Round
can truncate digits through the new MidpointRounding.ToZero. For positive numbers,MidpointRounding.ToNegativeInfinity
has the same effect while for negative numbers the equivalent isMidpointRounding.ToPositiveInfinity
.These lines:
Produce :
我将留下十进制数的解决方案。
这里的一些小数解决方案很容易溢出(如果我们传递一个非常大的小数,并且该方法将尝试将其相乘)。
Tim Lloyd 的解决方案可以防止溢出,但速度不太快。
下面的解决方案大约快了 2 倍并且没有溢出问题:
I will leave the solution for decimal numbers.
Some of the solutions for decimals here are prone to overflow (if we pass a very large decimal number and the method will try to multiply it).
Tim Lloyd's solution is protected from overflow but it's not too fast.
The following solution is about 2 times faster and doesn't have an overflow problem:
这是一个老问题,但许多答案表现不佳或在处理大数字时溢出。我认为 D. Nesterov 的答案是最好的:稳健、简单且快速。我只想补充我的两分钱。
我玩弄了 小数还查看了源代码。来自
public Decimal (int lo, int mid, int hi, bool isNegative, byte scale)
构造函数文档。知道了这一点,我的第一个方法是创建另一个小数,其小数位数对应于我想要丢弃的小数,然后截断它,最后创建具有所需小数位数的小数。
这个方法并不比 D. Nesterov 的方法快,而且更复杂,所以我多尝试了一下。我的猜测是,必须创建辅助
十进制
并检索这些位两次会使速度变慢。在第二次尝试中,我操纵了 Decimal.GetBits(Decimal d) 方法 我自己。这个想法是根据需要将组件划分为 10 倍并缩小规模。该代码(很大程度上)基于 Decimal.InternalRoundFromZero(ref Decimal d, int小数计数)方法。我还没有进行严格的性能测试,但在 MacOS Sierra 10.12.6、3,06 GHz Intel Core i3 处理器和目标 .NetCore 2.1 上,此方法似乎比 D. Nesterov 的方法快得多(我不会给出数字,因为,正如我所提到的,我的测试并不严格)。由实现此功能的人来评估性能提升是否会因为增加的代码复杂性而得到回报。
This is an old question, but many anwsers don't perform well or overflow for big numbers. I think D. Nesterov answer is the best one: robust, simple and fast. I just want to add my two cents.
I played around with decimals and also checked out the source code. From the
public Decimal (int lo, int mid, int hi, bool isNegative, byte scale)
constructor documentation.Knowing this, my first approach was to create another
decimal
whose scale corresponds to the decimals that I wanted to discard, then truncate it and finally create a decimal with the desired scale.This method is not faster than D. Nesterov's and it is more complex, so I played around a little bit more. My guess is that having to create an auxiliar
decimal
and retrieving the bits twice is making it slower. On my second attempt, I manipulated the components returned by Decimal.GetBits(Decimal d) method myself. The idea is to divide the components by 10 as many times as needed and reduce the scale. The code is based (heavily) on the Decimal.InternalRoundFromZero(ref Decimal d, int decimalCount) method.I haven't performed rigorous performance tests, but on a MacOS Sierra 10.12.6, 3,06 GHz Intel Core i3 processor and targeting .NetCore 2.1 this method seems to be much faster than D. Nesterov's (I won't give numbers since, as I have mentioned, my tests are not rigorous). It is up to whoever implements this to evaluate whether or not the performance gains pay off for the added code complexity.
((long)(3.4679 * 100)) / 100.0
会给出你想要的吗?Would
((long)(3.4679 * 100)) / 100.0
give what you want?这对你有用吗?
would this work for you?
如果您不太担心性能并且最终结果可以是字符串,则以下方法将能够适应浮动精度问题:
If you don't worry too much about performance and your end result can be a string, the following approach will be resilient to floating precision issues:
这是一个扩展方法:
Here is an extension method:
在某些情况下这可能就足够了。
我的小数值为
SubCent = 0.00999999999999999999999999999M 倾向于通过
string.Format("{0:N6}", SubCent ); 格式化为 |SubCent:0.010000| > 和许多其他格式选择。
我的要求不是对 SubCent 值进行四舍五入,但也不记录每个数字。
以下满足我的要求:
返回字符串: |SubCent:0.0099999|
为了容纳具有整数部分的值,以下是开始。
返回字符串:
Under some conditions this may suffice.
I had a decimal value of
SubCent = 0.0099999999999999999999999999M that tends to format to |SubCent:0.010000| via
string.Format("{0:N6}", SubCent );
and many other formatting choices.My requirement was not to round the SubCent value, but not log every digit either.
The following met my requirement:
Which returns the string : |SubCent:0.0099999|
To accommodate the value having an integer part the following is a start.
Which returns the string :
这是我对 TRUNC 函数的实现
Here is my implementation of TRUNC function
那这个呢?
what about this?
除了上述解决方案之外,我们还有另一种方式可以实现。
Apart from the above solutions,there is another way we can achieve .
这就是我所做的:
减去两个输入的数字,而不将小数点向上或向下舍入。
因为其他解决方案对我不起作用。
不知道它是否对其他人有用,我只是想分享这个:)
希望它对那些正在寻找与我类似的问题解决方案的人有用。谢谢
PS:我是一个初学者,所以请随时指出这一点。 :D
如果您实际上正在处理金钱,这很好,因为美分对吗?它只有 2 位小数,四舍五入是不行的。
This is what i did:
subtracting two inputted numbers without rounding up or down the decimals.
because the other solutions does not work for me.
don't know if it will work for others, i just want to share this :)
Hope it works tho for those who's finding solution to a problem similar to mine. Thanks
PS: i'm a beginner so feel free to point out something on this. :D
this is good if you're actually dealing with money, cause of the cents right? it only have 2 decimal places and rounding it is a no no.
我最喜欢的是
my favorite is
截断任何小数而不进行四舍五入的函数
function to truncate any decimal number without rounding
我正在使用此函数来截断字符串变量中小数点后的值
i am using this function to truncate value after decimal in a string variable
除了确保它处理 0 情况外,我对此只做了大约 0 次测试。
我的目标主要是无分支代码(如果您检查 Math.Sign() 的源代码,它里面有一个分支,至少在源代码中,也许它已经被优化了)。
这有一个限制(机械上),如果你想四舍五入小数位数为 28 或更大,它将溢出一个字节,但是,文档似乎表明无论如何都会违反十进制值的结构(或至少其准确性)限制)。
我的灵感最初来自 D. Nesterov 的回答,所以站在一些人的肩膀上......
I've done just about 0 testing on this except to make sure it handles the 0 case.
My objective was mostly branchless code (if you check source code for Math.Sign() it has a branch in it, at least in source, perhaps it's optimized out).
This has the limitation (mechanically) that it will overflow a byte if you want to round a decimal with a scale of 28 or more, however, documentation seems to indicate that would violate the structure of a decimal value anyway (or at least its accuracy limit).
My inspiration initially came from D. Nesterov's answer, so standing on some shoulders here...
实际上你想要 3.4679 中的 3.46 。
这只是字符的表示。因此与数学函数无关。数学函数无意于完成这项工作。
只需使用以下代码即可。
Actually you want 3.46 from 3.4679 .
This is only representation of characters.So there is nothing to do with math function.Math function is not intended to do this work.
Simply use the following code.
怎么样
what about