如何在Swift中获取特定数字类型的最小值(步幅)?

时间:2016-02-15 16:19:35

标签: swift

如何在Swift中获取特定数字类型的最小值(步幅)?我的意思是,最短的非零步幅。 例如1Int0.00...001Double等...

2 个答案:

答案 0 :(得分:2)

这已经在单独的评论中得到了部分解决,但要将它们全部整合在一起......

对于整数类型:

不同值之间的最小可能增量为1.这是整数定义的一部分,因此它不是那种类型的基本方面(并且不需要&t; t) be)用于查找它的特殊API。

(有人可以说successor构成了这样的API。但是人们也可以争辩说使用successor只能使用1会使你的代码更不易读。)

对于浮点类型:

没有一个可能的最小增量。因为浮点类型使用基于指数的表示,所以可表示的浮点数之间的间距随指数而变化,如此数字行所示:

density of floating point numbers 该图片来自What Every Computer Scientist Should Know About Floating-Point Arithmetic,这是一个必不可少的读物,每个人都使用浮点数。您可以在维基百科的Unit in the Last PlaceMachine Epsilon页面中阅读有关该概念的更多信息。 Exploring Binary也有一个关于浮点间距的良好入门级读数。

返回Swift - FloatDouble类型符合FloatingPoint protocol(在Swift 3中,目前处于测试阶段)。这定义了IEEE 754 floating point formats的功能,其中包括:

  • 最后一个位置的单位,或ulp,它告诉您数字与下一个更大的可表示数字之间的增量(但对于某些边缘情况)。这与机器epsilon有关,但不一样,因为它随着价值而扩展。 (ulpOfOne与其他库称为机器epsilon的相同。)

  • nextUpnextDown,它们会告诉您最接近或多或少可表示的数字。

这是一个例子(方便地显示对于32位Float,最小增量比你想象的要快一个):

let ichi: Float = 1.0
ichi.ulp    // -> 1.192093e-07
ichi.nextUp // -> 1.00000012

let man: Float = 10_000
man.ulp    // -> 10000
man.nextUp // -> 10000.001

let oku: Float = 100_000_000
oku.ulp    // -> 8
oku.nextUp // -> 100000008.0

在Swift 2中,没有FloatingPoint协议,但您可以使用从C导入的等效POSIX常量/函数:FLT_EPSILONDBL_EPSILON定义为1.0和下一个可表示值之间的差异,nextafter函数可以找到任何值的增量。

答案 1 :(得分:0)

您可以导入Darwin来获取这些号码,而您正在寻找的号码将是

DBL_MIN
FLT_MIN
Int.min

然而,这些不是很好的'我们会签署0.00 ... 01和Int之类的数字,因此使用Uint8.min会给你0.