使用 NSNumberFormatter 生成小数点后尾随零的数字
Posted
技术标签:
【中文标题】使用 NSNumberFormatter 生成小数点后尾随零的数字【英文标题】:Using NSNumberFormatter to generate number with trailing zeros after decimal 【发布时间】:2014-10-28 05:57:44 【问题描述】:在 Swift 中,您将如何创建一个 NSNumberFormatter
来保留小数点 (12.000) 后的尾随零,同时生成适合当前语言环境的数字?
我当前的代码和示例输出:
let formatter = NSNumberFormatter()
formatter.numberStyle = .DecimalStyle
formatter.locale = NSLocale.currentLocale()
formatter.maximumFractionDigits = 10
var doubleNumString = "12.0"
println(formatter.numberFromString(doubleNumString)) //in English it prints 12, want it to print 12.0
var doubleNumString = "12.000"
println(formatter.numberFromString(doubleNumString)) //prints 12, want it to print 12.000
var doubleNumString = "12.125"
println(formatter.numberFromString(doubleNumString)) //prints 12.125 as expected
var doubleNumString = "1234"
println(formatter.numberFromString(doubleNumString)) //prints 1,234 as expected
我已经对其进行了编码,如果字符串以小数 ("12."
) 结尾,则它不会使用此格式化程序来生成数字,而是只显示数字,然后显示小数(但我需要改善这一点,因为某些语言从右到左阅读)。
一种解决方案是检查字符串是否包含句点,如果是,则检查其后面的所有数字是否为 0,如果是,则不要通过数字格式化程序运行它,而是只运行 int 值通过格式化程序然后附加/前置小数点后跟适当数量的 0。
有更好/更清洁的解决方案吗?
【问题讨论】:
一个 number 没有尾随零,只有它的 string 表示。 "12.0" 和 "12.000" 转换为 数字 给出完全相同的结果,并且无法将它们区分为数字。 – 为什么不能只使用字符串本身? @Martin 因为字符串始终为英文格式,并且输出数字需要遵守当前的语言环境,但如果字符串中存在尾随零,则还要保留它们。 然后您可以转换字符串->数字->字符串,但您必须计算尾随零的数量并将其设置为 minimum+maximumFractionDigits 以进行第二次转换。也许这有帮助,目前没有时间尝试并写一个答案。 【参考方案1】:正如 Martin R 所提到的,您可以将 minimumFractionDigits
和 maximumFractionDigits
设置为相同的数字,这将强制始终显示许多小数位数。要知道要显示多少,您需要在小数点后取一个子字符串到末尾并计算其元素。为了知道是否所有小数位都是 0,我创建了一个辅助方法,该方法将该子字符串转换为一个数字,如果它等于 0,那么你就知道它们都是 0。
不幸的是,您需要根据原始字符串编号使用几个不同的NSNumberFormatter
s 将字符串转换为本地化编号。因此,如果它确实包含小数,并且它之后的所有内容都是 0,那么您需要创建一个不同的格式化程序,将字符串转换为数字,然后将该数字转换为字符串,以便根据用户的语言环境显示它。否则,您可以使用原始数字格式化程序。
【讨论】:
【参考方案2】:此功能可满足您的要求。从语言环境(例如 en_US)传递相同的 &
+ (NSString*) stringForString:(NSString*) string forLocale:(NSString*) toLocaleCode fromLocal:(NSString*) fromLocaleCode
NSLocale *fromLocale = [[NSLocale alloc] initWithLocaleIdentifier:fromLocaleCode];
NSNumberFormatter *sourceFormatter = [[NSNumberFormatter alloc] init];
[sourceFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
[sourceFormatter setUsesGroupingSeparator:NO];
[sourceFormatter setLocale:fromLocale];
NSNumber *localizedNumber = [sourceFormatter numberFromString:string];
if (!localizedNumber)
return string;
NSLocale *toLocale = [[NSLocale alloc] initWithLocaleIdentifier:toLocaleCode];
NSNumberFormatter *destinationFormatter = [[NSNumberFormatter alloc] init];
[destinationFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
[destinationFormatter setUsesGroupingSeparator:NO];
[destinationFormatter setLocale:toLocale];
NSString *localizedString = [destinationFormatter stringFromNumber:localizedNumber];
//add the zeros which were dropped because of the sourceDecimalString number conversion e.g. 0.20 is converted to 0.2
if (localizedString.length < string.length)
NSRange rangeOfDecimal = [string rangeOfString:sourceFormatter.decimalSeparator];
if (rangeOfDecimal.location != NSNotFound)
NSString* sourceDecimalString = [string substringFromIndex:rangeOfDecimal.location];
rangeOfDecimal = [localizedString rangeOfString:destinationFormatter.decimalSeparator];
if (rangeOfDecimal.location != NSNotFound)
NSString* destinationDecimalString = [localizedString substringFromIndex:rangeOfDecimal.location];
if (destinationDecimalString.length < sourceDecimalString.length)
int difference = sourceDecimalString.length - destinationDecimalString.length;
int toalDecimalDigits = (destinationDecimalString.length - 1) + difference; //-1 to remove '.'
destinationFormatter.minimumFractionDigits = toalDecimalDigits;
destinationFormatter.maximumFractionDigits = toalDecimalDigits;
localizedString = [destinationFormatter stringFromNumber:localizedNumber];
else//this indicates no decimal separator in the return string
int toalDecimalDigits = (sourceDecimalString.length - 1); //-1 to remove '.'
destinationFormatter.minimumFractionDigits = toalDecimalDigits;
destinationFormatter.maximumFractionDigits = toalDecimalDigits;
localizedString = [destinationFormatter stringFromNumber:localizedNumber];
return localizedString;
【讨论】:
以上是关于使用 NSNumberFormatter 生成小数点后尾随零的数字的主要内容,如果未能解决你的问题,请参考以下文章
NSNumberFormatter 仅四舍五入到小数点后 3 位
NSNumberFormatter 适用于小数分隔符但不适用于逗号分隔符
带有数字样式的 NSNumberFormatter NSNumberFormatterCurrencyStyle 逗号问题