Delphi 的 Round() 似乎是不确定的

问题描述

我面临着一个奇怪的情况,同一台机器上的同一个程序执行 Round() 相同的浮点值并不总是给出相同的结果。起初我认为它必须是由于有点翻转或其他原因造成的小故障,但它一直回来。现在它也开始发生在完全不同的机器上。糟糕的结果很少出现,大约每周一次。当他们这样做时,他们似乎一直在发生,直到程序重新启动。然而,这可能是巧合。到目前为止,我一直无法随意复制它。顺便说一下,这一切都发生在主线程上。

我考虑添加的一项检查是 Round 是否一直指向相同的内存地址。还有其他想法吗?

2020-12-28 08:30:19.411 DBGrid1.Fields[17].AsString: 0,239999994635582
2020-12-28 08:30:19.411 FloatToStr(DBGrid1.Fields[17].AsFloat): 0,239999994635582
2020-12-28 08:30:19.411 FloatToStr(1000 * DBGrid1.Fields[17].AsFloat): 239,999994635582
2020-12-28 08:30:19.411 IntToStr(Round(1000 * DBGrid1.Fields[17].AsFloat)): 239
2020-12-28 08:30:19.411 FloatToStr(DBGrid1.Fields[17].AsSingle): 0,239999994635582
2020-12-28 08:30:19.411 FloatToStr(1000 * DBGrid1.Fields[17].AsSingle): 239,999994635582
2020-12-28 08:30:19.411 IntToStr(Round(1000 * DBGrid1.Fields[17].AsSingle)): 239
2020-12-28 08:30:19.411 FloatToStr(DBGrid1.Fields[17].AsExtended): 0,239999994635582
2020-12-28 08:30:19.412 FloatToStr(1000 * DBGrid1.Fields[17].AsExtended): 239,999994635582
2020-12-28 08:30:19.412 IntToStr(Round(1000 * DBGrid1.Fields[17].AsExtended)): 239
2020-12-28 08:30:19.412 CurrToStr(DBGrid1.Fields[17].AsCurrency): 0,2399
2020-12-28 08:30:19.412 CurrToStr(1000 * DBGrid1.Fields[17].AsCurrency): 239,9
2020-12-28 08:30:19.412 IntToStr(Round(1000 * DBGrid1.Fields[17].AsCurrency)): 239
2020-12-28 08:30:19.412 FloatToStr(Query1.FieldByName('FIELD').AsFloat): 0,239999994635582
2020-12-28 08:30:19.412 FloatToStr(1000 * Query1.FieldByName('FIELD').AsFloat): 239,999994635582
2020-12-28 08:30:19.412 IntToStr(Round(1000 * Query1.FieldByName('FIELD').AsFloat)): 239
2020-12-28 08:30:19.412 FloatToStr(Query1.FieldByName('FIELD').AsSingle): 0,239999994635582
2020-12-28 08:30:19.412 FloatToStr(1000 * Query1.FieldByName('FIELD').AsSingle): 239,999994635582
2020-12-28 08:30:19.413 IntToStr(Round(1000 * Query1.FieldByName('FIELD').AsSingle)): 239
2020-12-28 08:30:19.413 FloatToStr(Query1.FieldByName('FIELD').AsExtended): 0,239999994635582
2020-12-28 08:30:19.413 FloatToStr(1000 * Query1.FieldByName('FIELD').AsExtended): 239,999994635582
2020-12-28 08:30:19.413 IntToStr(Round(1000 * Query1.FieldByName('FIELD').AsExtended)): 239
2020-12-28 08:30:19.413 CurrToStr(Query1.FieldByName('FIELD').AsCurrency): 0,2399
2020-12-28 08:30:19.413 CurrToStr(1000 * Query1.FieldByName('FIELD').AsCurrency): 239,9
2020-12-28 08:30:19.413 IntToStr(Round(1000 * Query1.FieldByName('FIELD').AsCurrency)): 239
2020-12-28 08:30:19.413 CurrToStr(Query1.FieldByName('FIELD').AsCurrency): 0,9
2020-12-28 08:30:19.413 IntToStr(Round(1000 * Query1.FieldByName('FIELD').AsCurrency)): 239
2020-12-28 08:30:19.414 BinToHex(DBGrid1.Fields[17].AsFloat): 00000000008FC2F5FC3F
2020-12-28 08:40:46.461 DBGrid1.Fields[17].AsString: 0,239999994635582
2020-12-28 08:40:46.462 FloatToStr(DBGrid1.Fields[17].AsFloat): 0,239999994635582
2020-12-28 08:40:46.463 FloatToStr(1000 * DBGrid1.Fields[17].AsFloat): 239,999994635582
2020-12-28 08:40:46.463 IntToStr(Round(1000 * DBGrid1.Fields[17].AsFloat)): 240
2020-12-28 08:40:46.463 FloatToStr(DBGrid1.Fields[17].AsSingle): 0,239999994635582
2020-12-28 08:40:46.463 FloatToStr(1000 * DBGrid1.Fields[17].AsSingle): 239,999994635582
2020-12-28 08:40:46.463 IntToStr(Round(1000 * DBGrid1.Fields[17].AsSingle)): 240
2020-12-28 08:40:46.463 FloatToStr(DBGrid1.Fields[17].AsExtended): 0,239999994635582
2020-12-28 08:40:46.463 FloatToStr(1000 * DBGrid1.Fields[17].AsExtended): 239,999994635582
2020-12-28 08:40:46.463 IntToStr(Round(1000 * DBGrid1.Fields[17].AsExtended)): 240
2020-12-28 08:40:46.463 CurrToStr(DBGrid1.Fields[17].AsCurrency): 0,24
2020-12-28 08:40:46.463 CurrToStr(1000 * DBGrid1.Fields[17].AsCurrency): 240
2020-12-28 08:40:46.463 IntToStr(Round(1000 * DBGrid1.Fields[17].AsCurrency)): 240
2020-12-28 08:40:46.463 FloatToStr(Query1.FieldByName('FIELD').AsFloat): 0,239999994635582
2020-12-28 08:40:46.463 FloatToStr(1000 * Query1.FieldByName('FIELD').AsFloat): 239,999994635582
2020-12-28 08:40:46.463 IntToStr(Round(1000 * Query1.FieldByName('FIELD').AsFloat)): 240
2020-12-28 08:40:46.463 FloatToStr(Query1.FieldByName('FIELD').AsSingle): 0,239999994635582
2020-12-28 08:40:46.464 FloatToStr(1000 * Query1.FieldByName('FIELD').AsSingle): 239,999994635582
2020-12-28 08:40:46.464 IntToStr(Round(1000 * Query1.FieldByName('FIELD').AsSingle)): 240
2020-12-28 08:40:46.464 FloatToStr(Query1.FieldByName('FIELD').AsExtended): 0,239999994635582
2020-12-28 08:40:46.464 FloatToStr(1000 * Query1.FieldByName('FIELD').AsExtended): 239,999994635582
2020-12-28 08:40:46.464 IntToStr(Round(1000 * Query1.FieldByName('FIELD').AsExtended)): 240
2020-12-28 08:40:46.464 CurrToStr(Query1.FieldByName('FIELD').AsCurrency): 0,24
2020-12-28 08:40:46.464 CurrToStr(1000 * Query1.FieldByName('FIELD').AsCurrency): 240
2020-12-28 08:40:46.464 IntToStr(Round(1000 * Query1.FieldByName('FIELD').AsCurrency)): 240
2020-12-28 08:40:46.464 CurrToStr(Query1.FieldByName('FIELD').AsCurrency): 0,24
2020-12-28 08:40:46.464 CurrToStr(1000 * Query1.FieldByName('FIELD').AsCurrency): 240
2020-12-28 08:40:46.465 IntToStr(Round(1000 * Query1.FieldByName('FIELD').AsCurrency)): 240
2020-12-28 08:40:46.465 BinToHex(DBGrid1.Fields[17].AsFloat): 00000000008FC2F5FC3F

解决方法

Round 是确定性的。但是,它的行为取决于流行的浮点舍入模式及其参数。程序中的其他内容正在改变舍入模式。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...