NSDecimalNumber的小数部分 [英] Fractional Part of NSDecimalNumber

查看:287
本文介绍了NSDecimalNumber的小数部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用NSDecimalNumber存储货币值.我正在尝试编写一种称为"cents"的方法,该方法以NSString返回数字的小数部分,如果数字<则以前导0开头. 10.所以基本上

I'm using NSDecimalNumber to store a value for currency. I'm trying to write a method called "cents" which returns the decimal portion of the number as an NSString with a leading 0 if the number is < 10. So basically

NSDecimalNumber *n = [[NSDecimalNumber alloc] initWithString:@"1234.55"];

NSString *s = [object cents:n];

我正在尝试设计一种方法,该方法将以字符串形式返回01、02等,最多返回99.我似乎无法弄清楚如何以这种格式将尾数作为字符串返回.我感觉好像缺少一种便捷的方法,但是我再次查看了文档,却没有发现任何对我不利的事情.

And I'm trying to craft a method that will return 01, 02, etc...up to 99 as a string. I can't seem to figure out how to return the mantissa as a string in this format. I feel like I'm missing a convenience method but I looked at the documentation again and don't see anything jumping out at me.

推荐答案

更新:这是一个相对较旧的答案,但看来人们仍在寻找它.我想对其进行更新以确保正确性—我最初回答该问题的原因只是为了演示如何从double中提取特定的小数位,但是我并不主张将其用作表示货币信息的方式.

Update: This is a relatively old answer, but it looks like people are still finding it. I want to update this for correctness — I originally answered the question as I did simply to demonstrate how one could pull out specific decimal places from a double, but I do not advocate this as a way to represent currency information.

从不使用浮点数表示货币信息.一旦开始处理十进制数字(就像处理带美分的美元一样),就会在代码中引入可能的浮点错误.计算机不能准确表示所有十进制值(例如,1/100.0,例如1美分,在我的计算机上表示为0.01000000000000000020816681711721685132943093776702880859375).根据您计划代表的货币,存储基本数量(在本例中为美分)的数量总是更正确.

Never use floating-point numbers to represent currency information. As soon as you start dealing with decimal numbers (as you would with dollars with cents), you introduce possible floating point errors into your code. A computer cannot represent all decimal values accurately (1/100.0, for instance, 1 cent, is represented as 0.01000000000000000020816681711721685132943093776702880859375 on my machine). Depending on which currencies you plan on representing, it is always more correct to store a quantity in terms of its base amount (in this case, cents).

如果您以整数美分来存储美元值,则对于大多数操作而言,您永远都不会遇到浮点错误,并且将美分转换为美元以进行格式化也很容易.例如,如果您需要征税,或将美分值乘以double,请执行此操作以获取double值,请应用

If you store your dollar values in terms of integral cents, you'll never run into floating-point errors for most operations, and it's trivially easy to convert cents into dollars for formatting. If you need to apply tax, for instance, or multiply your cents value by a double, do that to get a double value, apply banker's rounding to round to the nearest cent, and convert back to an integer.

如果您要支持多种不同的货币,它会变得更加复杂,但是有多种处理方法.

It gets more complicated than that if you're trying to support multiple different currencies, but there are ways of dealing with that.

tl; dr 不要使用浮点数来表示货币,这样会更快乐,而且更正确. NSDecimalNumber能够准确(精确地)表示十进制值,但是一旦转换为double/float,就会冒引入浮点错误的风险.

tl;dr Don't use floating-point numbers to represent currency and you'll be much happier, and more correct. NSDecimalNumber is able to accurately (and precisely) represent decimal values, but as soon as you convert to double/float, you run the risk of introducing floating-point errors.

这可以相对容易地完成:

This can be done relatively easily:

  1. 获取十进制数字的double值(假设该数字不是太大以至于不能存储为双精度数,这将起作用).
  2. 在单独的变量中,将double强制转换为整数.
  3. 将两个数字都乘以100,以解决精度损失(基本上是转换为美分),并从原始数字中减去美元以获得美分的数量.
  4. 返回字符串.
  1. Get the double value of the decimal number (this will work assuming the number is not too large to store in a double).
  2. In a separate variable, cast the double to an integer.
  3. Multiply both numbers by 100 to account for loss of precision (essentially, convert to cents) and subtract dollars from the original to get the number of cents.
  4. Return in a string.

(这是处理所有十进制数字的通用公式–使用NSDecimalNumber只需一点胶水代码即可使其起作用).

(This is a general formula for working with all decimal numbers – working with NSDecimalNumber just requires a little bit of glue code to get it to work).

实际上,它看起来像这样(在NSDecimalNumber类别中):

In practice, it would look like this (in an NSDecimalNumber category):

- (NSString *)cents {
    double value = [self doubleValue];
    unsigned dollars = (unsigned)value;
    unsigned cents = (value * 100) - (dollars * 100);

    return [NSString stringWithFormat:@"%02u", cents];
}

这篇关于NSDecimalNumber的小数部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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