Jam*_*B41 7 xcode objective-c mantissa nsdecimalnumber
我正在使用NSDecimalNumber存储货币值.我正在尝试编写一个名为"cents"的方法,如果数字<10,则返回数字的小数部分作为NSString,前导0.所以基本上
NSDecimalNumber *n = [[NSDecimalNumber alloc] initWithString:@"1234.55"];
NSString *s = [object cents:n];
Run Code Online (Sandbox Code Playgroud)
而我正在尝试制作一个方法,它将返回01,02等...最多99作为一个字符串.我似乎无法弄清楚如何以这种格式将尾数作为字符串返回.我觉得我错过了一种方便的方法,但我再次查看了文档,并没有看到任何东西向我跳出来.
Ita*_*ber 11
更新:这是一个相对陈旧的答案,但看起来人们仍在寻找它.我想更新这个以获得正确性 - 我最初回答了这个问题,因为我只是为了演示如何从a中提取特定的小数位double,但我并不主张这是一种表示货币信息的方法.
切勿使用浮点数来表示货币信息.一旦开始处理十进制数字(就像你用美元一样处理美分),就会在代码中引入可能的浮点错误.计算机无法准确表示所有小数值(1/100.0例如,1美分,表示为0.01000000000000000020816681711721685132943093776702880859375在我的机器上).根据您计划代表的货币,以基本金额(在本例中为美分)存储数量总是更正确.
如果以积分美分的形式存储美元价值,那么大多数操作都不会遇到浮点错误,并且很容易将美分换成美元进行格式化.例如,如果您需要应用税,或者将您的美分值乘以a double,那么为了得到一个double值,应用银行家的舍入来舍入到最接近的分数,然后转换回整数.
如果你试图支持多种不同的货币,它会变得更复杂,但有办法解决这个问题.
tl; dr不要使用浮点数来表示货币,你会更开心,也更正确.NSDecimalNumber能够准确(并精确地)表示十进制值,但是一旦转换为double/ float,就会产生引入浮点错误的风险.
这可以相对容易地完成:
double十进制数的值(假设数字不是太大而无法存储在double中,这将起作用).double转换为整数.(这是处理所有十进制数的通用公式 - NSDecimalNumber只需要一点胶水代码就可以使它工作).
在实践中,它看起来像这样(在一个NSDecimalNumber类别中):
- (NSString *)cents {
double value = [self doubleValue];
unsigned dollars = (unsigned)value;
unsigned cents = (value * 100) - (dollars * 100);
return [NSString stringWithFormat:@"%02u", cents];
}
Run Code Online (Sandbox Code Playgroud)
ham*_*ene 11
这是一个更安全的实现,它将使用不适合的值double:
@implementation NSDecimalNumber (centsStringAddition)
- (NSString*) centsString;
{
NSDecimal value = [self decimalValue];
NSDecimal dollars;
NSDecimalRound(&dollars, &value, 0, NSRoundPlain);
NSDecimal cents;
NSDecimalSubtract(&cents, &value, &dollars, NSRoundPlain);
double dv = [[[NSDecimalNumber decimalNumberWithDecimal:cents] decimalNumberByMultiplyingByPowerOf10:2] doubleValue];
return [NSString stringWithFormat:@"%02d", (int)dv];
}
@end
这打印01:
NSDecimalNumber* dn = [[NSDecimalNumber alloc] initWithString:@"123456789012345678901234567890.0108"];
NSLog(@"%@", [dn centsString]);
| 归档时间: |
|
| 查看次数: |
6532 次 |
| 最近记录: |