这是Xcode 7.3.1 Playground中的简单代码:
var str = "8.7" print(Double(str))
输出令人惊讶: Optional(8.6999999999999993)
另外,Float(str)
给出:8.69999981
对这个家伙有什么想法或理由吗?任何对此的引用将不胜感激。
另外,我该如何将“ 8.7”转换为Double(或Float)的8.7?
编辑
迅速地:
(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
第二个问题是:为什么数字有时打印为“ 8.7”,有时打印为“ 8.6999999999999993”?
let str = "8.7"
print(Double(str)) // Optional(8.6999999999999993)
let x = 8.7
print(x) // 8.7
是Double("8.7")
从不同8.7
?一个比另一个更精确吗?
要回答这些问题,我们需要知道print()
函数的工作方式:
CustomStringConvertible
,则打印函数将调用其description
属性并将结果打印到标准输出。CustomDebugStringConvertible
,则打印函数调用is 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 Optional
不会 不 符合CustomStringConvertible
,而是要CustomDebugStringConvertible
。因此,print函数调用的debugDescription
属性Optional
,该属性又调用debugDescription
基础的Double
。因此,除了是可选的以外,数字输出与
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
创建一个具有较少十进制数字的字符串。该字符串可以转换为a Double
并返回给相同结果的字符串。
debugDescription
创建具有更多十进制数字的字符串,以便任何两个不同的浮点值将产生不同的输出。
摘要:
description
和debugDescription
方法使用不同的精度来转换为字符串。作为结果,因此,根据您的情况,您可能希望在打印可选件之前将其拆开:
let str = "8.7"
if let d = Double(str) {
print(d) // 8.7
}
为了更好地控制,请使用NSNumberFormatter
该%.<precision>f
格式或对格式进行格式化。
另一种选择是使用(NS)DecimalNumber
而不是Double
我还是一名学生,刚开始学习java编程语言,我只是想问一下如何将函数main中的参数从字符串转换为double,就像将字符串转换为整数一样。pasreInt(arg)
问题内容: 我有一个双,其值是10,000,000.00(千万)。我必须将其转换为。当使用该方法时,我会得到 “ 1.0E7”,它遵循规范是正确的。不幸的是,我需要“ 10,000,000.00”(或等价的语言,具体取决于语言环境)。 如何做到这一点? 问题答案: 尝试之一 NumberFormat http://java.sun.com/javase/6/docs/api/java/text/N
我正在创建一个基本的GUI,它接受用户输入的金额,并用预先存在的金额减去它。然而,它不会让我运行下面的一个,因为我得到了一个字符串不能转换为double的错误。这里使用parseInt方法不起作用,因为im使用getText方法。
问题内容: 我需要以给定的精度将double转换为字符串。(或DecimalFormat)可以完成这项工作,但基准测试显示,即使转换速度不是非常快(在我的计算机上转换一百万个数字,大约需要1-3秒),它的速度仍然很慢。 有什么更好的方法吗? 更新:基准化结果 从0到1000000的随机数,结果是以毫秒为单位的操作数(Java 1.7.0_45) 更新: Java 10 + Ryu 问题答案: 免责
我需要将字符串值转换为带点的双精度值。下面是简单的代码 当我给出10000或100000这样的值时,它是有效的。帮助我克服这个问题。
问题内容: 我有一个文本框,其中将包含 货币 字符串,然后需要将该字符串转换为双精度以对其执行一些操作。 → 这需要在所有客户端发生。我别无选择,只能将 货币 字符串保留为输入的 货币 字符串,但需要将其强制转换/转换为双精度以进行一些数学运算。 问题答案: 删除所有非点/数字: