- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我如何在 Delphi 中使用类似 Math.Round
和 MidpointRounding.AwayFromZero
的 c#?
等同于:
double d = 2.125;
Console.WriteLine(Math.Round(d, 2, MidpointRounding.AwayFromZero));
输出:2.13
在德尔福?
最佳答案
我相信 Delphi RTL 的 SimpleRoundTo函数本质上是这样做的,至少如果 FPU 舍入模式是“正确的”。请仔细阅读其文档和实现,然后确定它是否足以满足您的目的。
但请注意,设置像这样的单个舍入操作的舍入模式是使用全局更改来解决局部问题。这可能会导致问题(多线程、库等)。
奖金喋喋不休:如果问题是关于“常规”舍入(到整数),我想我已经尝试过类似的方法
function RoundMidpAway(const X: Real): Integer;
begin
Result := Trunc(X);
if Abs(Frac(X)) >= 0.5 then
Inc(Result, Sign(X));
end;
相反。
当然,即使对于 n 小数位的一般情况,也可以编写类似的函数。 (但要小心正确处理边缘情况、溢出、浮点问题等。)
更新:我相信以下内容可以解决问题(而且速度很快):
function RoundMidpAway(const X: Real): Integer; overload;
begin
Result := Trunc(X);
if Abs(Frac(X)) >= 0.5 then
Inc(Result, Sign(X));
end;
function RoundMidpAway(const X: Real; ADigit: integer): Real; overload;
const
PowersOfTen: array[-10..10] of Real =
(
0.0000000001,
0.000000001,
0.00000001,
0.0000001,
0.000001,
0.00001,
0.0001,
0.001,
0.01,
0.1,
1,
10,
100,
1000,
10000,
100000,
1000000,
10000000,
100000000,
1000000000,
10000000000
);
var
MagnifiedValue: Real;
begin
if not InRange(ADigit, Low(PowersOfTen), High(PowersOfTen)) then
raise EInvalidArgument.Create('Invalid digit index.');
MagnifiedValue := X * PowersOfTen[-ADigit];
Result := RoundMidpAway(MagnifiedValue) * PowersOfTen[ADigit];
end;
当然,如果您要在生产代码中使用此功能,您还需要添加至少 50 个单元测试用例来测试其正确性(每天运行)。
更新:我相信以下版本更稳定:
function RoundMidpAway(const X: Real; ADigit: integer): Real; overload;
const
FuzzFactor = 1000;
DoubleResolution = 1E-15 * FuzzFactor;
PowersOfTen: array[-10..10] of Real =
(
0.0000000001,
0.000000001,
0.00000001,
0.0000001,
0.000001,
0.00001,
0.0001,
0.001,
0.01,
0.1,
1,
10,
100,
1000,
10000,
100000,
1000000,
10000000,
100000000,
1000000000,
10000000000
);
var
MagnifiedValue: Real;
TruncatedValue: Real;
begin
if not InRange(ADigit, Low(PowersOfTen), High(PowersOfTen)) then
raise EInvalidArgument.Create('Invalid digit index.');
MagnifiedValue := X * PowersOfTen[-ADigit];
TruncatedValue := Int(MagnifiedValue);
if CompareValue(Abs(Frac(MagnifiedValue)), 0.5, DoubleResolution * PowersOfTen[-ADigit]) >= EqualsValue then
TruncatedValue := TruncatedValue + Sign(MagnifiedValue);
Result := TruncatedValue * PowersOfTen[ADigit];
end;
但我还没有完全测试过。 (目前它通过了 900+ unit test cases ,但我认为测试套件还不够。)
关于c# - 在 Delphi 中,Math.Round() 与 MidpointRounding.AwayFromZero 的等效项是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56732297/
在C#中,MidpointRounding.ToEven和MidpointRounding.AwayFromZero这两种小数舍入策略在精度上有区别吗?我的意思是两者都确保在四舍五入的数字之间均匀分布
我遇到了一个相当烦人的问题。 假设我有小数 2.5,我希望它四舍五入。我的所有研究都告诉我: Math.Round(2.5, 0, MidpointRounding.AwayFromZero) 会给我
我正在做一个应用程序,我需要始终使用 MidpointRounding.AwayFromZero 对数字进行四舍五入,但每次进行四舍五入时,我都必须编写以下语句 Math.Round(xxx, ddd
我需要使用不同于默认“四舍五入”Mathf.Round() 的中点舍入规则。 Mathf.Round() 没有中点舍入参数,所以我使用 System.Math.Round()。 C# 有不同的中点舍入
我需要使用不同于默认“四舍五入”Mathf.Round() 的中点舍入规则。 Mathf.Round() 没有中点舍入参数,所以我使用 System.Math.Round()。 C# 有不同的中点舍入
这个问题在这里已经有了答案: Why does .NET use banker's rounding as default? (5 个答案) 关闭 9 年前。 以下适用: var rounded =
在 .NET 中,为什么 System.Math.Round(1.035, 2, MidpointRounding.AwayFromZero) 产生 1.03 而不是 1.04?我觉得我的问题的答案在
我想从 c# 中的这一行在 javascript 中获得相同的结果: round = Math.Round((17245.22 / 100), 2, MidpointRounding.AwayFrom
为什么这会导致 0 而不是 1? Math.Round(0.5, 0, MidpointRounding.AwayFromZero) 这是一个例子:http://ideone.com/ayMVO 最佳
我使用的是 Visual Studio Professional 2012。我创建了一个新的 C# ConsoleApplication,目标是 .NET Framework 4.5,代码如下:
在 .NET 中,为什么 System.Math.Round(27.2351, 2, MidpointRounding.AwayFromZero) 产生 27.24 而不是 27.23? 第三个数字是
我有一个 Math.Round 的错误,没有任何解释。当我做 Math.Round(81.725, 2, MidpointRounding.AwayFromZero) 结果是 81,72 但是当我用
我如何在 Delphi 中使用类似 Math.Round 和 MidpointRounding.AwayFromZero 的 c#? 等同于: double d = 2.125; Console.Wr
我是一名优秀的程序员,十分优秀!