想写四舍六入五留双....函数....估计难度挺大100分送上(100)

  • 主题发起人 主题发起人 楚辞
  • 开始时间 开始时间

楚辞

Unregistered / Unconfirmed
GUEST, unregistred user!
使用EDIT1,EDIT2,BUTTON1 在文本框1里填入数据,点击BUTTON按钮,然后在文本框2显示结果.单位现在实行新的数据修约规则,将以前实行了四舍五入规则改为四舍六入五留双,规则的具体方法是:(一)当尾数小于或等于4时,直接将尾数舍去。例如将下列数字全部修约为四位有效数字,结果为:0.53664——0.5366 10.2731——10.27 18.5049——18.50 0.58344——0.5834 16.4005——16.40 27.1829——27.18 (二)当尾数大于或等于6时,将尾数舍去并向前一位进位。例如将下列数字全部修约为四位有效数字,结果为:0.53666——0.5367 8.3176——8.318 16.7777——16.78 0.58387——0.5839 10.29501——10.30 21.0191——21.02 (三)当尾数为5,而尾数后面的数字均为0时,应看尾数“5”的前一位:若前一位数字此时为奇数,就应向前进一位;若前一位数字此时为偶数,则应将尾数舍去。数字“0”在此时应被视为偶数。例如将下列数字全部修约为四位有效数字,结果为:0.153050——0.1530 12.6450——12.64 18.2750——18.28 0.153750——0.1538 12.7350——12.74 21.845000——21.84 (四)当尾数为5,而尾数“5”的后面还有任何不是0的数字时,无论前一位在此时为奇数还是偶数,也无论“5”后面不为0的数字在哪一位上,都应向前进一位。例如将下列数字全部修约为四位有效数字,结果为:0.326552——0.3266 12.73507——12.74 21.84502——21.85 12.64501——12.65 18.27509——18.28 38.305000001——38.31 按照四舍六入五留双规则进行数字修约时,也应像四舍五入规则那样,一次性修约到指定的位数,不可以进行数次修约,否则得到的结果也有可能是错误的。例如将数字10.2749945001修约为四位有效数字时,应一步到位:10.2749945001——10.27(正确)。如果按照四舍六入五留双规则分步修约将得到错误结果:10.2749945001——10.274995——10.275——10.28(错误)。
 
So Easy,Convert to string自己写个函数 GetRound(pSourceString//源数,pLength//保留位数) return ...
 
照你的要求,写了个函数,不过只是随便测试了一些你贴出的数据,反正得到的结果都是你的正确结果,给你参考一下。且这个函数应该还能优化一下的。function myround(source: string): string;var x: integer; gettail: string;begin if Int(StrToFloat(source)) < 1 then x := 7 else x := 6; result := IntToStr(Length(source)); case StrToInt(source[x]) of 6..9: source[x - 1] := IntToStr(StrToInt(source[x - 1]) + 1)[1]; 5: begin gettail := Copy(source, x + 1, Length(source) - x + 1); if StrToInt(gettail) > 0 then source[x - 1] := IntToStr(StrToInt(source[x - 1]) + 1)[1] else if StrToInt(source[x - 1]) mod 2 = 1 then source[x - 1] := IntToStr(StrToInt(source[x - 1]) + 1)[1]; end; end; result := Copy(source, 1, x - 1);end;
 
没有必要自己写函数,你说的算法实际上就是 Intel CPU 使用的 “银行家舍入法”。delphi 提供的函数就符合“银行家舍入法”。你可以试试:Edit2.Text:=floattostr(roundto(strtofloat(Edit1.Text),-4));0.53664 -> 0.53660.5366501 -> 0.53670.53665 -> 0.53660.53675 -> 0.53680.53685 -> 0.5368
 
delphi默认的就是银行家法,想不是还要另外设置,具体可以全文检索 round。
 
同意,直接用Delphi Round函数即可不折腾
 
哦.这个函数是四舍五入的,不是我所要的四舍六入五留双....
 
procedure TForm1.Button1Click(Sender: TObject);begin Edit2.Text:=floattostr(roundto(strtofloat(Edit1.Text),-4));end;//提示roundto是示申报的标识符
 
Vsun:有下面疑问见又斜杠后function myround(source: string): string;var x: integer; gettail: string;begin if Int(StrToFloat(source)) < 1 then x := 7 else x := 6;//这个6与7代表什么? result := IntToStr(Length(source)); case StrToInt(source[x]) of 6..9: source[x - 1] := IntToStr(StrToInt(source[x - 1]) + 1)[1];//6..9与页面的5是代表有5.6.7.8.9五种情况,那1.2.3.4种情况了? 5: begin gettail := Copy(source, x + 1, Length(source) - x + 1); if StrToInt(gettail) > 0 then source[x - 1] := IntToStr(StrToInt(source[x - 1]) + 1)[1] else if StrToInt(source[x - 1]) mod 2 = 1 then source[x - 1] := IntToStr(StrToInt(source[x - 1]) + 1)[1]; end; end; result := Copy(source, 1, x - 1);end;
 
Vsun:procedure TForm1.Edit3Change(Sender: TObject);beginedit3.Text:=myround(4);end;[Error] Unit1.pas(70): Incompatible types: 'String' and 'Integer'
 
procedure TForm1.Button2Click(Sender: TObject);beginedit3.Text:=floattostr(strtofloat(myround('0.0000')));end;//报错
 
>>哦.这个函数是四舍五入的,不是我所要的四舍六入五留双.... 看看帮助再说吧:Delphi syntax:function Round(X: Extended): Int64;DescriptionIn Delphi, the Round function rounds a real-type value to an integer-type value.X is a real-type expression. Round returns an Int64 value that is the value of X rounded to the nearest whole number. If X is exactly halfway between two whole numbers, the result is always the even number. This method of rounding is often called "Banker's Rounding".If the rounded value of X is not within the Int64 range, a runtime error is generated, which can be handled using the EInvalidOp exception.Note: The behavior of Round can be affected by the Set8087CW procedure or SetRoundMode function.经常看到有人提出 Round 函数的问题,很多人都认为这个函数就是四舍五入算法,其实是错误的。在 VB, VBScript, C#, J#, T-SQL 中 Round 函数都是采用 Banker's rounding(银行家舍入)算法,即四舍六入五取偶。详细的说是这样:四舍六入五考虑, 五后非零就进一, 五后皆零看奇偶, 五前为偶应舍去, 五前为奇要进一. 事实上这也是 IEEE 规定的舍入标准。因此所有符合 IEEE 标准的语言都是采用这一算法的。虽然“四舍五入”是我国最早提出的算法,值得我们自豪,但不能因此就认为它始终是先进的。毕竟它已经有近二千年历史了(大约一千七百多年前,天文学家杨伟就已明确提出了“四舍五入法”)。四舍五入算法逢五就要进位,带来的问题就是结果偏大,尤其是在大量的数据统计中。4舍6入没有什么特别,就是5 比较特殊,如果5舍就会偏小,如果5入就会偏大,Banker 舍入法是取最接近的偶数,这样就比四舍五入准确性高,我们看下面的例子。 原始数据 四舍五入 Banker 舍入 1.1249 1.12 1.12 1.1248 1.12 1.12 1.1252 1.13 1.12 1.1250 1.13 1.12 1.1354 1.14 1.14 1.1351 1.14 1.14 1.1352 1.14 1.14 1.1353 1.14 1.14 1.1361 1.14 1.14 1.1360 1.14 1.14 ---------------------------------------------------------------- 平均值 1.1313 1.134 1.132这组原始数据它们的平均值是1.1313;如果我们按四舍五入保留两位小数,它们的平均值是1.134,误差是+0.0027;如果我们采用 Banker 舍入,结果是1.1320,误差是+0.0007。可以看出四舍五入的误差要大得多。而在金融计算和统计中是精度是非常重要的,这也是 Banker 舍入的名称的由来,银行家是不喜欢四舍五入的。四舍五入是我上小学时数学课程的内容,大多数中国人都坚信舍入小数时应该使用这个算法。所幸据说现在的小学数学课程已经将 Banker's rounding 正式写入课本。希望以后的孩子大概不会再有现在的问题了。关于编程中 Round 函数和 Banker 舍入的信息,可以参考微软的 Knowledge Base:Q194983 PRB: Round Function Different in VBA 6 and Excel SpreadsheetQ196652 HOWTO: Implement Custom Rounding Procedures
 
谢谢kaida.在uses 中加上math,后就不报错了.
 
遗憾的是没有把vsun的看明白.得仔细看看....谢谢大家了.
 
结贴吧...谢谢各位FW了....
 
还折腾,前面不是说了吗,Round就是这个功能
 
太猛攻了....Vsun,唯一缺点就是后面的0没有了....我的qq号:328844156
 

Similar threads

S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
900
SUNSTONE的Delphi笔记
S
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
824
DelphiTeacher的专栏
D
后退
顶部