У меня есть вариант использования, когда я хочу определить, имеет ли NSDecimalNumber в swift дробный компонент (отличный от 0). Я могу обрезать десятичную часть, но это связано с созданием нового NSDecimalNumber, и я хотел бы избежать этого, если это возможно.
Я делаю это в вычисляемом свойстве, поэтому я хотел бы, чтобы оно было максимально эффективным. В настоящее время мое расширение выглядит на игровой площадке так:
extension NSDecimalNumber {
func decimalNumberRoundedToDigits(withDecimals: UInt8, roundingMode: NSRoundingMode = NSRoundingMode.RoundPlain) -> NSDecimalNumber
{
// round to required decimals
let disp = decimalNumberByRoundingAccordingToBehavior(NSDecimalNumberHandler(roundingMode: roundingMode, scale: Int16(withDecimals), raiseOnExactness: false, raiseOnOverflow: false, raiseOnUnderflow: false, raiseOnDivideByZero: false));
return disp;
}
// Convert the least significant byte into a signed 8-bit integer
// Currently just truncates the fractional portion - I would like
// to test it instead and only round if there are decimals.
var safeByteValue: Int8 {
get {
let bits = UInt8(decimalNumberRoundedToDigits(0).longLongValue & 0xFF);
return Int8(bitPattern: bits);
}
};
}
// just a test loop for demonstration
for i in 0...256
{
print(NSDecimalNumber(unsignedInt: UInt32(bitPattern: Int32(i))).safeByteValue);
}
1000000
, а показатель степени равен-20
или0
. Вы всегда должны округлить, а затем сравнить с исходным числом. Другого безопасного пути нет. - person Sulthan   schedule 14.01.2016longLongValue
сначала преобразуютNSDecimalNumber
вdouble
, обрезая всю дополнительную точность. Обратите внимание, чтоNSDecimalNumber
использует десятичную арифметику, а не двоичную. Это означает, что все вычисления выполняются медленнее, чем сdouble
. Я не уверен, что это хорошая идея для приложения, основанного на битовых шаблонах, то есть на двоичной арифметике. - person Sulthan   schedule 14.01.2016