有没有更简洁的方法来重写F#函数?
以下是一个函数,用于将数字转换为具有所需精度和前导符号的字符串:有没有更简洁的方法来重写F#函数?,f#,F#,以下是一个函数,用于将数字转换为具有所需精度和前导符号的字符串: let formatValueSign (precision: decimal) (value: decimal) = let precisionString = match precision with | 0.1m -> "{0:+#.0;-#.0; 0.0}" | 0.01m -> "{0:+#.00;-#.0
let formatValueSign (precision: decimal) (value: decimal) =
let precisionString =
match precision with
| 0.1m -> "{0:+#.0;-#.0; 0.0}"
| 0.01m -> "{0:+#.00;-#.00; 0.00}"
| 0.001m -> "{0:+#.000;-#.000; 0.000}"
| 0.0001m -> "{0:+#.0000;-#.0000; 0.0000}"
| 0.00001m -> "{0:+#.00000;-#.00000; 0.00000}"
| 0.000001m -> "{0:+#.000000;-#.000000; 0.000000}"
| _ -> "{0:+#0;-#0;0}"
String.Format(precisionString, value)
预期输出在数字前面有符号,精度由十进制数字表示,但如果更方便的话,也可以作为i传递,其中精度为pown 0.1m i
有没有办法让这更简洁?如果我正确地理解了您的需求,我认为类似的事情本质上是一样的:
(Decimal.Round(value / precision) * precision).ToString()
它还处理精度>1的情况,例如:
formatValueSign 100m -12345.6789m -> "-12300"
如果需要,可以调整ToString()
部分以生成前导的+
符号。就我个人而言,我会将其分为两个函数:一个用于生成精度正确的十进制数,另一个用于根据您的喜好对其进行格式化
最后一个想法:我可能会将精度定义为整数指数(例如,
-2
而不是0.01m
),因为当前签名接受的精度不是10的幂。最好将无效值设为不可表示的IMHO。您可以使用log10
计算格式字符串中的零数,然后动态生成格式字符串。以下不正确处理拐角的情况,但它适用于范围在你的范围内的情况:
let formatValueSign (precision: decimal) (value: decimal) =
let places = int (log10 (float (1.0m/precision)))
let zeros = String.replicate places "0"
let precisionString = sprintf "{0:+#.%s;-#.%s; 0.%s}" zeros zeros zeros
String.Format(precisionString, value)
我选择Tomas的答案是因为它符合开箱即用的要求输出。但是关于精度,您是对的,使用位数比使用十进制数字表示精度更有意义。