VB.Net舍入错误 [英] VB.Net Rounding error

查看:87
本文介绍了VB.Net舍入错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

1)回合(1580/11,4)= 143.6364. 2)圆(143.6364 * 11,8)= 1580.00040000

我该如何退回1580.我希望在十进制情况1)下为4位精度,在情况2)下为8位精度.不允许截断.

请帮忙.

解决方案

像这样四舍五入时,您的第一个四舍五入的精度至少要比反向四舍五入大1位.

示例:

  var  res = Math.Round(1580d/11d, 9 );
 var  outVal = Math.Round(res *  11  8 ); 



那是C#语法,但是应该类似于VB.


假设您知道以整数开头. . .

  double  a = System.Math.Round(1580/11. 0  4 );
 double  Delta =  0 . 00001 ;
 int  b =( int )(System.Math.Floor((a *  0 )+ Delta)); 



换句话说,将您的乘数乘以11-不会得出确切的整数(浮点算术很少这样做)-加一小部分以确保您刚好在整数上,而不是在整数下,然后取取下一个下一个整数的底限.

[抱歉,这是C#,但是VB中的功能/技术相同,只是更改了语法]

如果您不是以整数开头,则需要知道您有多少个小数位-并相应地缩放值-因此,如果3dp(例如1580.123)这样做了:

  double  a = System.Math.Round( 1580  .123/11 . 0  4 );
 double  Delta =  0 . 00001 ;
 double  b = System.Math.Floor((a *  1000  *  0 )+ Delta)/您似乎很困惑. 1  st 操作的结果四舍五入到小数点后四位,并且您真的想获得2  nd 操作的结果,该操作取决于第一个操作的精度为小数点后8位.确实没有任何意义,但是您可以尝试解释为什么这样做.
对于不等于1580的结果.第一次运算的结果实际上是定期的十进制小数时,将其四舍五入到小数点后四位: [^ ] .63636363等.因此,一旦开始四舍五入, 最有可能在您开始时不会得到相同的结果.这不是错误,而是四舍五入时遇到的问题所固有的.
您可以做的是将GUI状态与逻辑分开.在显示结果时,您始终可以进行四舍五入,但是保留原始结果以进行进一步的计算.

问候,

-MRB


1)round(1580/11,4) = 143.6364. 2) round(143.6364*11,8) = 1580.00040000

How can I get 1580 back. I want 4 digits precision in decimal case 1) and 8 digits precision in case 2). No truncating allowed.

Please help. Thanx in advance.

解决方案

When you round like that, your first rounding needs to have a precision of at least 1 digit greater than the reverse rounding.

Example:

var res = Math.Round(1580d / 11d, 9);
var outVal = Math.Round(res * 11, 8);



That''s C# syntax, but it should be similar to VB.


Assuming you KNOW that you started with an integer . . .

double a = System.Math.Round(1580/11.0, 4);
double Delta = 0.00001;
int b = (int)(System.Math.Floor((a * 11.0) + Delta));



In other words, do your multiplication by 11 - it won''t come out as an exact integer (floating point arithmetic rarely does) - add a small amount to make sure you are just over, not just under, an integer - and take Floor to get next lower integer.

[sorry, this is C# but the functions / techniques are the same in VB, just change the syntax]

If you didn''t start with an integer, you need to know how many decimal places you had - and scale values accordingly - so if 3dp (e.g. 1580.123) do:

double a = System.Math.Round(1580.123/11.0, 4);
double Delta = 0.00001;
double b = System.Math.Floor((a * 1000 * 11.0) + Delta) / 1000;




If you''ve rounded your intermediate result to 4dp but know you started with a value that wasn''t necessarily integral and may have had up to 8 valid dp, you CAN''T, even theoretically, retrieve the original value accurately to 8dp.

e.g. 1580.00000001 and 1580.00000002 come out the same if divided by 11 and then rounded to 4dp - so you cannot distinguish between them when reversing the operation, so one of them must come out ''wrong''.


You seem to be confused. The result of your 1st operation is rounded to 4 decimal places and you really want to have the result of the 2nd operation which depends on the first to have a precision of 8 decimal places. That doesn''t really make any sens, but you could try to explain why you are doing this.
As to the result not being equal to 1580. The result of the first operation was rounded to four decimal places when it was really a periodic decimal fraction:[^] .63636363 etc.. So once you start rounding you''ll most likely won''t get the same result where you started from. This is not an error but inherent to the problems encountered when doing rounding.
What you can do is separate GUI state from you logic. You can always do rounding when displaying the results, but keep the original result for doing further calculations.

Regards,

-MRB


这篇关于VB.Net舍入错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆