iOS:格式化十进制数字 [英] iOS: formatting decimal numbers

查看:122
本文介绍了iOS:格式化十进制数字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 NSDecimalNumber 代表金额。
我想将其打印为999 999 999 999 999 999,00,无论在何处。
我该怎么办?

I have an NSDecimalNumber representing a money amount. I want to print it as "999 999 999 999 999 999,00", regardless on the locale. How do I do that?

NSNumberFormatter打印出来我代码为1 000 000 000 000 000 000,00(苹果工程师似乎从来没有将iPhone设计为财务软件平台)。

NSNumberFormatter prints me 1 000 000 000 000 000 000,00 instead (it seems Apple engineers never designed the iPhone to be a platform for financial software).

[NSDecimalNumber description] [NSDecimalNumber descriptionWithLocale] 都打印正确的值。如何格式化结果,将分组分隔符设置为 @\ u2006,小数分隔符设置为 @**,**,小数分隔符后面的正好2位小数?

[NSDecimalNumber description] and [NSDecimalNumber descriptionWithLocale] both print correct value. How can I format the result, with grouping separator set to @"\u2006", decimal separator to @"**,**", and exactly 2 decimal digits after the decimal seperator?

提前致谢!

更新:
这是我的解决方案,10倍于Sulthan:

Update: Here's my solution, 10x to Sulthan:

@implementation NSDecimalNumber(MiscUtils)

-(NSString*)moneyToString
{
    static NSDecimalNumberHandler* s_handler = nil;
    if( !s_handler )
        s_handler = [ [ NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain scale:2 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO ] retain ];

    NSDecimalNumber *dec = [ self decimalNumberByRoundingAccordingToBehavior:s_handler ];
    NSString* str = [ dec description ];
    NSRange rDot = [ str rangeOfString:@"." ];
    int nIntDigits = str.length;
    int nFracDigits = 0;
    if( rDot.length > 0 )
    {
        nIntDigits = rDot.location;
        nFracDigits = str.length - ( rDot.location + 1 );
    }
    int nGroupSeparators = ( nIntDigits - 1 ) / 3;

    NSMutableString* res = [ NSMutableString stringWithCapacity:nIntDigits + nGroupSeparators + 3 ];
    NSString *groupingSeparator = @"\u2006";

    int nFirstGroup = ( nIntDigits % 3 );
    int nextInd = 0;
    if( nFirstGroup )
    {
        [ res appendString:[ str substringToIndex:nFirstGroup ] ];
        nextInd = nFirstGroup;
    }

    while( nextInd < nIntDigits )
    {
        if( res.length > 0 )
            [ res appendString:groupingSeparator ];
        [ res appendString:[ str substringWithRange:NSMakeRange( nextInd, 3 ) ] ];
        nextInd += 3;
    }

    if( nFracDigits > 0 )
    {
        if( nFracDigits > 2 )
            nFracDigits = 2;
        [ res appendString:@"," ];
        [ res appendString:[ str substringWithRange:NSMakeRange( rDot.location + 1, nFracDigits ) ] ];
        while( nFracDigits < 2 )
        {
            [ res appendString:@"0" ];
            nFracDigits++;
        }
    }
    else
        [ res appendString:@",00" ];
//  DLog( "formatDecimal: %@ -> %@", dec, res );
    return res;
}
@end 


推荐答案

我有同样的问题。我被告知 NSNumberFormatter 首先将所有内容转换为 double 。我是怎么解决的?这很容易,只需编写自己的格式化程序。

I had the same problem. I was told that NSNumberFormatter converts everything to a double first. How did I solve it? It's easy, just write your own formatter.


  1. 首先将小数点圈成2位小数。

  2. 将其描述作为字符串。

  3. 在字符串中查找小数点(。)并将其替换为您想要的小数点。

  4. 每次从小数点到左边的三位数,插入一个分组分隔符。

  1. First round the decimal to 2 decimal digits.
  2. Get its description as a string.
  3. Find decimal point (.) in the string and replace it with the one you want.
  4. After every three digits from the decimal point to the left, insert a grouping separator.

这篇关于iOS:格式化十进制数字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆