c#的四舍五入,问题很简单,答案很迷惑

Comer 2009-03-04 04:40:27
Math.Round(x)

通过程序测试了几个个数据,列表如下:

x值 反回值 正常值(中国人会计习惯)
0.5 0 1
-0.5 0 -1
0.6 1 1
-0.6 -1 -1

查了点资料,C#的Round是四舍六入五取偶

查到了点网上转载多的代码:
double ChinaRound(double value, int decimals)
{
if (value < 0)
{
return Math.Round(value + 5 / Math.Pow(10, decimals + 1), decimals, MidpointRounding.AwayFromZero);
}
else
{
return Math.Round(value, decimals, MidpointRounding.AwayFromZero);
}
}
//这断代码处理不了-0.5四舍五入到整数,已测试

public static double Round(double d, int i)
{
if (d >= 0)
{
d += 5 * Math.Pow(10, -(i + 1));
}
else
{
d += -5 * Math.Pow(10, -(i + 1));
}
string str = d.ToString();
string[] strs = str.Split('.');
int idot = str.IndexOf('.');
string prestr = strs[0];
string poststr = strs[1];
if (poststr.Length > i)
{
poststr = str.Substring(idot + 1, i);
}
string strd = prestr + "." + poststr;
d = Double.Parse(strd);
return d;
}
//这断代码处理-0.5四舍五入到整数会报异常,已测试

...全文
2676 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
seawaycao 2011-09-04
  • 打赏
  • 举报
回复
即-0.5四舍五入后为-1.
seawaycao 2011-09-04
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 awen360 的回复:]

引用 22 楼 vrhero 的回复:
引用 21 楼 comerliang 的回复:
刚用-0.5测试了,结果是0

不可能...你用的什么版本?

晕死,-0.5四舍五入就应该是0呀,5要进位的。难道还要是-1啊。小学数学是怎么学的啊。
[/Quote]

我用的是VS2010版本,经过“四舍五入”测试:
Console.WriteLine(Math.Round(-0.5, 0, MidpointRounding.AwayFromZero));
输出为:-1
alexgao624 2010-04-13
  • 打赏
  • 举报
回复
用这种方法试试
float ave = float.Parse((x).ToString("F2"));
awen360 2009-09-08
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 vrhero 的回复:]
引用 21 楼 comerliang 的回复:
刚用-0.5测试了,结果是0

不可能...你用的什么版本?
[/Quote]
晕死,-0.5四舍五入就应该是0呀,5要进位的。难道还要是-1啊。小学数学是怎么学的啊。
guoyichao 2009-03-05
  • 打赏
  • 举报
回复
中文MSDN能不看最好不看,万不得已要看也要尽量少看。

AwayFromZero When a number is halfway between two others, it is rounded toward the nearest number that is away from zero.

如果指定了 AwayFromZero,则将返回 -3,因为它是精度为零且与零最接近的数字。

这个明显是对AwayFromZero的翻译错误,AwayFromZero顾名思义就是离0远,实际含义就是当一个数字在其他2个中间则取整为最接近于离0远的那个。由于浮点数存在精度问题所以"the nearest"的修饰还是比较严谨的。
vrhero 2009-03-05
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 comerliang 的回复:]
刚用-0.5测试了,结果是0
[/Quote]
不可能...你用的什么版本?
Comer 2009-03-05
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 vrhero 的回复:]
直接用这个...
C# codereturnMath.Round(value, decimals, MidpointRounding.AwayFromZero);

刚经过测试,这个问题已经不存在了...我想应该是微软在.NET 2.0 SP1以后进行了修补...
[/Quote]

刚用-0.5测试了,结果是0
yinjianjing 2009-03-05
  • 打赏
  • 举报
回复
很久不接触这样的东西了,不知道你们在说什么了,郁闷
vrhero 2009-03-05
  • 打赏
  • 举报
回复
// 摘要:
// 当一个数字是其他两个数字的中间值时,会将其舍入为两个值中绝对值较小的值。
AwayFromZero = 1,
------------------
不过这个描述上的错误仍然没有改...不知道微软中国的人都在干什么...

你可以参考英文MSDN原文...

AwayFromZero When a number is halfway between two others, it is rounded toward the nearest number that is away from zero.

你再去看看中文MSDN MidpointRounding 枚举中的描述...里面又清清楚楚地说...

如果指定了 AwayFromZero,则将返回 -3,因为它是精度为零且与零最接近的数字。

取绝对值较大的值
vrhero 2009-03-05
  • 打赏
  • 举报
回复
你找的这段示例代码是我三年前写的...那时是有这个问题的,之后应该是做了修补...因为一直没用到所以也没注意...
vrhero 2009-03-05
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 comerliang 的回复:]
彻底迷糊了

0.44449保留2位结果到底是0.44还是0.45呢?说啥的都有啊


好像0.44才是正确的,excel也是显示0.44


用D7测试了下,也是0.44,不是D7的rondto()用的啥标准
[/Quote]
0.44449保留2位结果肯定是0.44...这是小学数学常识...不会管你若干位后有没有大过5的,只看保留位以后的那一位...
vrhero 2009-03-05
  • 打赏
  • 举报
回复
直接用这个...
return Math.Round(value, decimals, MidpointRounding.AwayFromZero);


刚经过测试,这个问题已经不存在了...我想应该是微软在.NET 2.0 SP1以后进行了修补...
Comer 2009-03-05
  • 打赏
  • 举报
回复
彻底迷糊了

0.44449保留2位结果到底是0.44还是0.45呢?说啥的都有啊


好像0.44才是正确的,excel也是显示0.44


用D7测试了下,也是0.44,不是D7的rondto()用的啥标准
ATGO 2009-03-05
  • 打赏
  • 举报
回复
很搞笑,留言。
Comer 2009-03-05
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 sp1234 的回复:]
这样怎么样?C# codepublicstaticdoubleMyRound(doubled,inti)
{returnMath.Sign(d)*Math.Round(Math.Abs(d)+1*Math.Pow(10,-(i+10)), i);
}
[/Quote]

用这个测试如下代码,结果是-0.44,也不对

        private void button3_Click(object sender, EventArgs e)
{
double d = bRound(-0.44449, 2);

MessageBox.Show(d.ToString());
}
Comer 2009-03-05
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 sp1234 的回复:]
呵呵,是 Round(double value, int digits, MidpointRounding mode) 重载!

我测试了一下:

?Math.Round(0.5,0,System.MidpointRounding.AwayFromZero)
1.0
?Math.Round(-0.5,0,System.MidpointRounding.AwayFromZero)
-1.0

[/Quote]

看下定义吧,对负数好像不行吧?

using System.Runtime.InteropServices;

namespace System
{
// 摘要:
// 指定数学舍入方法应如何处理两个数字间的中间值。
[ComVisible(true)]
public enum MidpointRounding
{
// 摘要:
// 当一个数字是其他两个数字的中间值时,会将其舍入为最接近的偶数。
ToEven = 0,
//
// 摘要:
// 当一个数字是其他两个数字的中间值时,会将其舍入为两个值中绝对值较小的值。
AwayFromZero = 1,
}
}
人工智能算法 2009-03-04
  • 打赏
  • 举报
回复
嗯嗯 已经有人说到点上了 我就不说了
lovefootball 2009-03-04
  • 打赏
  • 举报
回复
2.0里面Math.Round提供了MidpointRounding枚举
具体可以参考http://msdn.microsoft.com/zh-cn/library/system.midpointrounding.aspx
  • 打赏
  • 举报
回复
高手过招 小弟旁观
  • 打赏
  • 举报
回复
呵呵,是 Round(double value, int digits, MidpointRounding mode) 重载!

我测试了一下:

?Math.Round(0.5,0,System.MidpointRounding.AwayFromZero)
1.0
?Math.Round(-0.5,0,System.MidpointRounding.AwayFromZero)
-1.0
加载更多回复(7)

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧