iOS Float / Double无需舍入

时间:2015-06-03 09:33:17

标签: ios objective-c swift

好的我有一个非常愚蠢的问题。我需要将一个浮动分开两个:

  • 第一部分包含整数部分和小数点后的两位数
  • 第二项应包含浮动
  • 中的第三和第四位数字

重要的是我不想要任何舍入(无论是向上还是向下)。几乎以下几点:

12.8 => 12.80 && 00
12.8999999999 => 12.89 && 99
12.899999 => 12.89 && 99
12.0005 => 12.00 && 05

格式字符串方法

无论如何我都需要小数点后正好4位数,所以我需要使用%.4f或%f(并剪切最后两个组件)才能处理12.8 => 12.8000。但是,当小数点后自动向上舍入时,该数字有许多9位:

let test = 122.899999999999
let sut = String(format: "%f", test) // 122.900000 instead of 122.899999

回合方法

我尝试使用标准的C floor方法,因为它应该向下舍入我的浮子。但是,如果小数点后面的9位大于​​我的“分隔符”,那么就像圆形一样:

let test = 122.89999999999999

let divider = 10000.0

let sut = (Double(floor(test * divider)) / divider) // 122.9 instead of 122.8999

因此,非常欢迎任何建议:)

2 个答案:

答案 0 :(得分:1)

不要使用浮点数,float不准确。使用NSDecimalNumberNSDecimalNumber类提供定点算术功能。它们被设计用于执行基数为10的计算,而不会出现精度损失且具有可预测的舍入行为。这使它成为表示货币的更好选择,而不是像double这样的浮点数据类型。然而,权衡的是它们使用起来更复杂。

NSDecimalNumber *price1 = [[NSDecimalNumber alloc] initWithFloat:15.99f]] ;
NSDecimalNumber *price1 = [[NSDecimalNumber alloc] initWithFloat:29.99f]] ;
NSLog(@"Subtotal: %@", [price1 decimalNumberByAdding:price2]); 

输出45.98。

See this.

修改

以下是关于NSDecimalNumber的Apple文档。

答案 1 :(得分:-2)

我相信这个功能可以满足您的需求:

func returnWhatINeed(number : Double) -> (fst : Double, snd : Int, trd : Int) {

  // get the number without any decimals
  let noDecimals = Double(Int(number))
  // get the decimals
  let decimals = number - noDecimals
  // get the first four decimals after the floating point
  var tempDecimals = Int(decimals * 10000)

  // get the fourth decimal
  let fourth = tempDecimals % 10
  tempDecimals /= 10
  // get the third decimal
  let third = tempDecimals % 10
  // get the first two decimals
  tempDecimals /= 10


  return (noDecimals + Double(tempDecimals) / 100, third, fourth)
}

用法:

let result = returnWhatINeed(122.8479999999999)

result.fst将包含仅包含前两位小数的浮点数:122.84

result.sndresult.trd将包含第三个(7)和第四个(9)小数

请注意,这是解决您问题的快速方法。将来您应该使用NSNumberFormatter来获得预期的格式。