简体   繁体   English

NumberFormatter string(from:NSNumber) 方法有小数位问题

[英]NumberFormatter string(from:NSNumber) method has issues with decimal places

Here is my code这是我的代码

let ns = NumberFormatter.init()
ns.allowsFloats = true
ns.maximumFractionDigits = 18 //This is a variable value
ns.minimumFractionDigits = 18 //This is a variable value
ns.roundingMode = .floor
ns.numberStyle = .decimal
let doubleValueOfDecimal : Double = 12.95699999999998
let numb = NSNumber.init(value: doubleValueOfDecimal)
print(numb)
let string = ns.string(from: numb)
print(string)

The following is the output and input doubleValueOfDecimal = 2.95699999999998 Output 2.95699999999998 Optional("2.956999999999980000") But if I input以下是输出和输入doubleValueOfDecimal = 2.95699999999998 Output 2.95699999999998 Optional("2.956999999999980000")但是如果我输入

doubleValueOfDecimal =  12.95699999999998

The output is输出是

12.95699999999998
Optional("12.957000000000000000")

The string conversion rounds up the value.字符串转换对值进行四舍五入。 Can someone explain me how this works?有人可以解释我这是如何工作的吗?

The string conversion is rounding up the decimal places when I want it to show the exact number.当我希望它显示确切数字时,字符串转换会将小数位四舍五入。

You are falling down the cracks between the expectations of the behaviour of decimal numbers and the reality that Float and Double are binary floating-point , that is the fractional part of decimal numbers are sums of 1/10's, 1/100's etc. while for binary numbers it is sums of 1/2's, 1/4's etc. and some values exact in one are inexact in the other and vice-versa.您正在打破对十进制数行为的期望与FloatDouble二进制浮点数的现实之间的裂缝,即十进制数的小数部分是 1/10、1/100 等的和。而对于二进制数是 1/2's, 1/4's 等的总和,一些精确的值在另一个中不精确,反之亦然。

Change your code to include:更改您的代码以包括:

let doubleValueOfDecimal : Decimal = Decimal(string:"12.95699999999998")!
let numb = doubleValueOfDecimal as NSDecimalNumber

and the output is probably what you expect:输出可能是您所期望的:

12.95699999999998
12.956999999999980000

The Decimal type is a decimal floating-point value type, NSDecimalNumber is a subclass of NSNumber which holds a Decimal value. Decimal类型是十进制浮点值类型, NSDecimalNumberNSNumber的子类,它保存一个Decimal值。

HTH HTH

(Note: you have to initialise the Decimal from a string as using a numeric literal appears to involve the Swift compiler using binary floating point at some point in the process...) (注意:您必须从字符串初始化Decimal ,因为使用数字文字似乎涉及 Swift 编译器在过程中的某个点使用二进制浮点数...)

Use wrapper method of NSNumber class.使用NSNumber类的包装方法。 ` `

 print(numb.stringValue)
let ns = NumberFormatter.init()
ns.allowsFloats = true
ns.maximumFractionDigits = 18
ns.minimumFractionDigits = 18
ns.roundingMode = .floor
ns.numberStyle = .decimal
let numb = NSNumber.init(value: doubleValueOfDecimal)
print(numb)
let string = ns.string(from: numb)
print(numb.stringValue)

Below Output for 2.95699999999998 , 12.95699999999998 values.低于 2.95699999999998 的输出,12.95699999999998 值。

Output输出

2.95699999999998 2.95699999999998

2.95699999999998 2.95699999999998

12.95699999999998 12.95699999999998

12.95699999999998 12.95699999999998

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM