微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ios – swift:将字符串转换为double的问题

这是 Xcode 7.3.1 playground中的一个简单代码

var str =“8.7”
打印(双人间(STR))

输出令人惊讶:
可选(8.6999999999999993)

另外,Float(str)给出:8.69999981

对这个家伙的任何想法或原因?
任何对此的引用都将不胜感激.

另外,我应该如何将“8.7”​​转换为8.7为Double(或Float)?

编辑

在迅速:

(str为Nsstring).doubleValue返回8.7

现在,那没关系.但我的问题仍然没有得到完整答案.我们找到了另一种选择,但为什么我们不能依赖Double(“8.7”​​).请更深入地了解这一点.

编辑2

(“6.9”as Nsstring).doubleValue //打印6.9000000000000004

所以,这个问题又开始了.

解决方法

这里有两个不同的问题.首先 – 正如已经提到的那样
注释 – 二进制浮点数不能代表
准确地说是8.7. Swift使用IEEE 754标准进行表示
单精度和双精度浮点数,如果指定的话
let x = 8.7

然后,最接近的可表示数字存储在x中,即

8.699999999999999289457264239899814128875732421875

关于这方面的更多信息可以在优秀中找到
Q& A Is floating point math broken?.

第二个问题是:为什么数字有时打印为“8.7”
有时候是“8.6999999999999993”?

let str = "8.7"
print(Double(str)) // Optional(8.6999999999999993)

let x = 8.7
print(x) // 8.7

双倍(“8.7”​​)与8.7不同吗?比一个更准确
一个

要回答这些问题,我们需要知道print()
功能有效:

>如果参数符合customstringconvertible,则print函数调用其description属性并打印结果
到标准输出.
>否则,如果参数符合CustomDebugStringConvertible,
print函数调用是debugDescription属性并打印
结果为标准输出.
>否则,使用其他一些机制. (此处未导入我们的
目的.)

因此,Double类型符合customstringconvertible

let x = 8.7
print(x) // 8.7

产生相同的输出

let x = 8.7
print(x.description) // 8.7

但是会发生什么

let str = "8.7"
print(Double(str)) // Optional(8.6999999999999993)

Double(str)是可选的,struct可选不
符合customstringconvertible,但要符合
CustomDebugStringConvertible.因此打印功能调用
Optional的debugDescription属性,反过来
调用底层Double的debugDescription.
因此 – 除了可选之外 – 数字输出
与中相同

let x = 8.7
print(x.debugDescription) // 8.6999999999999993

但是description和debugDescription之间有什么区别
对于浮点值?从Swift源代码可以看出
最终都调用了swift_floatingPointToString
函数Stubs.cpp中,Debug参数分别设置为false和true.
这可以控制数字到字符串转换的精度:

int Precision = std::numeric_limits<T>::digits10;
  if (Debug) {
    Precision = std::numeric_limits<T>::max_digits10;
  }

有关这些常量的含义,请参阅http://en.cppreference.com/w/cpp/types/numeric_limits

> digits10 – 无需更改即可表示的小数位数,
> max_digits10 – 区分此类型的所有值所需的小数位数.

因此,description会创建一个十进制数较少的字符串.那
string可以转换为Double并返回给字符串
同样的结果.
debugDescription创建一个包含更多十进制数字的字符串,以便这样做
任何两个不同的浮点值都会产生不同的输出.

摘要

>大多数十进制数不能完全表示为二进制数
浮点值.
>浮动的描述和debugDescription方法
点类型使用不同的精度转换为a
串.作为结果,
>打印可选浮点值使用与转换非可选值不同的转换精度.

因此,在您的情况下,您可能想要打开可选项
在打印之前:

let str = "8.7"
if let d = Double(str) {
    print(d) // 8.7
}

为了更好地控制,请使用NSNumberFormatter或格式化
使用%.< precision> f格式打印.

一个选项可以是使用(NS)DecimalNumber而不是Double
(例如,对于货币金额),请参阅例如Round Issue in swift.

原文地址:https://www.jb51.cc/iOS/332878.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐