为什么NaN(不是数字)仅适用于双打?

Jam*_*Ide 42 c# types

我有一个包含两个可为空的十进制属性的业务类.第三个属性返回乘以其他两个属性的结果.如果两个可空类型的HasValue为真,那么我乘以并返回结果.如果一个或两个属性为null,我有一些返回值的选项:

  • 返回0
  • 抛出一个例外
  • 返回一个幻数(-1)
  • 返回小数?(编辑 - 见评论)

我认为我的一个选择是返回NaN,但我发现这只适用于double类型.为什么是这样?

对于记录,在这种情况下返回0是最有意义的,这是我打算做的事情,除非有人有更好的建议.

Meh*_*ari 38

.NET中的整数类型使用二进制补码系统进行表示.虽然他们可以为特殊值保留一些位模式,但他们选择不这样做.doublefloat使用一个完全不同的表示系统(IEEE 754),为NaN,+ Infinity,-Infinity保留一些特殊的位模式......

NaN和Infinity值对浮点运算更有意义的一个原因是运算可能会导致除零,这不仅因为除数实际上为零,而且因为它太小而无法用类型表示.结果,如果不是这种情况,你可能会有一些有效的计算神秘地抛出除零异常.对于int类型不会发生这种情况,因为它们是精确的并且没有精度错误.

decimal被设计用于"真实世界"十进制浮点数.它很少受到计算doublefloat计划的影响.什么NaN表达现实世界的数字?

仅仅留下它背后的原因,它就是它,我们无能为力,所以最好的方法是使用可空类型(它们旨在帮助确切地解决这种情况).这是解决这个问题的正确方法.如果您不想这样做(并且异常没有意义),您应该使用幻数解决方案.如果您选择这样做,只需确保它在有效结果域之外.

编辑(关于十进制的非常常见的误解):

正如MSDN所指出的,decimal不是固定点.这是一个浮点数:

十进制数是一个浮点值,由一个符号,一个数值组成,其中值中的每个数字范围从0到9,以及一个缩放系数,表示浮动小数点的位置,用于分隔积分和小数部分的数值.

  • "NaN会为真实世界的号码表达什么?" sqrt(-1)? (4认同)
  • Mark Pim:你真的想用十进制来进行复杂算术吗?;) (4认同)
  • @kervin:不,十进制是“十进制”浮点类型,与二进制浮点相反。它有指数和尾数,所以它是浮点数。 (3认同)
  • @Mehrdad:在复数算术中sqrt(-1)= sqrt({ - 1,0})= {0,1}.仅在Real算术中,sqrt(-1)可以被认为是"不是数字",因此由NaN表示. (3认同)
  • @Daniel:好点.这主要是作为一个笑话.这并不影响我的意思:如果一个十进制数的应用程序想要计算`sqrt(-1)`,那99%的致命错误应该会导致异常. (3认同)