自动安全地从双精度型转换为十进制型:以下安全吗?
在 C# 中按以下方式从双精度型转换为十进制是否安全:
int downtimeMinutes = 90;
TimeSpan duration = TimeSpan.FromHours(2d);
decimal calculatedDowntimePercent = duration.TotalMinutes > 0?
(downtimeMinutes / (decimal)duration.TotalMinutes) * 100.0m : 0.0m;
如果答案是肯定的,那么不用大惊小怪,我将标记为已接受。
Is it safe to cast from double to decimal in the following manner in C#:
int downtimeMinutes = 90;
TimeSpan duration = TimeSpan.FromHours(2d);
decimal calculatedDowntimePercent = duration.TotalMinutes > 0?
(downtimeMinutes / (decimal)duration.TotalMinutes) * 100.0m : 0.0m;
If the answer is yes, then no fuss, I'll just mark as accepted.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
一般来说,
double
->decimal
转换并不安全,因为decimal
的范围较小。但是,只要
TotalMinutes
小于最大decimal
值*就可以了。这是真的,因为 TimeSpan.MaxValue.TotalMinutes(double)decimal.MaxValue
(我相信TimeSpan
在内部使用long
。)所以:是的。
*:(79,228,162,514,264,337,593,543,950,335分钟是宇宙年龄的1.1×10^13倍)
In general,
double
->decimal
conversions aren't safe, becausedecimal
has a smaller range.However, as long as
TotalMinutes
is less than the maximumdecimal
value* it will be fine. This is true, becauseTimeSpan.MaxValue.TotalMinutes < (double)decimal.MaxValue
(I believeTimeSpan
uses along
internally.)So: yes.
*: (79,228,162,514,264,337,593,543,950,335 minutes is 1.1×10^13 times the age of the universe)
不,一般来说,从双精度型转换为十进制并不总是安全:
正如OP在对该问题的评论中所澄清的那样,“ safe”是“不会导致运行时异常”,上面显示将双精度型转换为小数时可能发生异常。
以上是许多 Google 员工来到这里的通用答案。然而,为了回答OP提出的特定问题,这里强烈表明代码不会抛出异常,即使在边缘情况下也是如此:
No, in general, casting from double to decimal is not always safe:
As OP clarified in a comment to the question, "safe" being "doesn't cause run time exceptions", the above shows that exceptions can occur when casting a double to a decimal.
The above is the generic answer many Googlers might've come here for. However, to also answer the specific question by OP, here's a strong indication that the code will not throw exceptions, even on edge cases:
是的,它是安全的,因为十进制具有更高的精度
http:// msdn.microsoft.com/en-us/library/364x0z75(VS.80).aspx
编译器将对其他非十进制数字进行强制转换,但它们都会适合十进制 * (参见警告)。
--
警告
Decimal 不是浮点类型。它的使命是始终保持精确性。而浮点数,例如 double (我主要使用它)则在精度上进行了权衡以适应非常大的数字)。非常大或非常小的数字不适合十进制。所以Lisa需要问问自己,运算的幅度是否有可能小于28位有效数字。 28 位有效数字足以满足大多数情况。
浮点适用于天文大数或无限小数......或产生足够精度的介于两者之间的运算。我应该查一下,但是 double 可以精确到小数点后几位(最多 7 或 8?),可以精确到正负几十亿。
在科学中,测量超出设备的准确性是没有意义的。在金融领域,通常逻辑选择是 double,因为在大多数情况下,double 在计算上效率更高(有时他们想要更高的准确性,但效率不值得为小数之类的东西而丢弃)。最后,我们都必须务实,将业务需求映射到数字领域。有些工具具有动态数字表示形式。 .net 中可能有相同的库。然而,这值得吗?有时是这样。通常这是矫枉过正的。
Yes it is safe, because decimal has greater precision
http://msdn.microsoft.com/en-us/library/364x0z75(VS.80).aspx
The compiler will put in casts around the other non decimal numbers, but they'll all fit into decimal * (see caveat).
--
Caveat
Decimal is not a floating point type. Its mandate is to always uphold precision. Whereas a floating point number such as double (which I mostly use) makes a tradeoff on precision to accommodate very large numbers). Very large or very small numbers will not fit into decimal. So Lisa needs to ask herself if the magnitude of the operation is likely to be less than 28 significant digital digits. 28 significant digits are adequate for most scenarios.
Floating point is good for astronomically large or infintessimally small numbers... or operations inbetween that yield enough accuracy. I should look this up, but double is okay for plus or minus a few billion with accuracy of up to several decimal points (up to 7 or 8?).
in the sciences there's no point measuring beyond the accuracy of your equipment. In finance, often the logical choice is double because a double is computationally more efficient for most situations (sometimes they want a bit more accuracy, but the efficiency is not worth throwing away for something like decimal). In the end we all have to get pragmatic and map business needs to a digital domain. There are tools out there that have a dynamic number representation. Probably there are libraries in .net for the same. However, is it worth it? Sometimes it is. Often it's overkill.