Потеря точности при поплавке с Swift

Я пытаюсь создать функцию для создания версии с плавающей точкой в ​​моем приложении с Swift. Он работает совершенно прямо сейчас, за исключением случаев, когда ему приходится создавать смешанное число (целая и фракционная часть).

В качестве примера ниже, когда я вызываю функцию с 0,4, она работает нормально, но не с 1.4, потому что она имеет целую часть (1). Кажется, когда я вычитаю всю часть (integerPart) на исходную величину, она теряет точность. Вы можете проверить это прямо на игровой площадке.

Примеры:

0.4 -> 2/5 1.4 -> 1 2/5 2.4 -> 2 2/5 0.5 -> 1/2 0.7 -> 7/10 etc... func fractionize(quantity: Float) -> String { let integerPart: Float = floor(quantity); var numerator: Float = quantity - integerPart; var firstNumerator: Float = numerator; var denominator: Float = 1; if (isInteger(quantity)) { return "\(Int(integerPart))"; } else { do { denominator++; numerator = firstNumerator * denominator; println(numerator); } while (!isInteger(numerator) && denominator <= 10); if (integerPart > 0) { if (isInteger(numerator)) { return "\(integerPart) \(Int(numerator))/\(Int(denominator))"; } else { return "\(quantity) couldn't be fractionized. Result = \(integerPart) \(numerator) / \(denominator)"; } } else { if (isInteger(numerator)) { return "\(Int(numerator))/\(Int(denominator))"; } else { return "\(quantity) couldn't be fractionized. Result = \(numerator) / \(denominator)"; } } } } fractionize(1.4); 

В качестве дополнительного примера он отлично работает с 1.5, но не с 1.4, 2.4, 3.4 и т. Д. … из-за того же. Я не знаю, как сделать хорошую субстрацию, чтобы метод isInteger работал нормально. Это моя функция isInteger. Я уже тестировал его, и он работает нормально:

 func isInteger(quantity: Float) -> Bool { return floor(quantity) == quantity; } 

Зайдите на детскую площадку, и вы увидите, что происходит, когда вы пытаетесь разбить 1,3 или 1,4, например.

2 Solutions collect form web for “Потеря точности при поплавке с Swift”

Вы должны вычислять целое число, чтобы избежать проблемы с плавающей точкой. Поэтому сначала конвертируйте float в целое число.

Вам нужен следующий код?

 func gcd(var m: Int, var n: Int) -> Int { if m < n { (m, n) = (n, m) } if n == 0 { return m } else if m % n == 0 { return n } else { return gcd(n, m % n) } } func fractionize(var quantity: Float) -> String { var i = 0 while quantity % 1 != 0 { quantity = quantity * 10 i += 1 } var numerator = Int(quantity) var denominator = Int(pow(Double(10), Double(i))) let divisor = gcd(numerator, denominator) numerator /= divisor denominator /= divisor var wholeNumber = 0 if numerator > denominator { wholeNumber = numerator / denominator numerator -= denominator * wholeNumber } if wholeNumber > 0 { return "\(wholeNumber) \(numerator)/\(denominator)" } else { return "\(numerator)/\(denominator)" } } println(fractionize(0.4)) // 2/5 println(fractionize(1.4)) // 1 2/5 println(fractionize(2.4)) // 2 2/5 println(fractionize(0.5)) // 1/2 println(fractionize(0.7)) // 7/10 

Если вам нужно полагаться на точные представления чисел, вы можете посмотреть в NSDecimalNumber, поскольку «нормальные» числа с плавающей запятой не могут точно выразить некоторые десятичные числа. См. Также этот хороший учебник .

Interesting Posts

Обнаружение, когда кнопка «назад» нажата на навигационной панели

Сохранение звука после эффекта в iOS

Core Data никогда не выпускает NSData, загружаемую из внешнего хранилища

Текст в UITextView Auto-Scrolled to Bottom

В чем разница между версией launchscreen.storyboard и main.storyboard

Passbook: Не удалось найти passTypeIdentifier в проходе?

Прокрутка вверх, когда вы нажимаете строку состояния

Когда мне нужно использовать Priority в iOS AutoLayout?

Функция Xcode INSTRUMENTS для проверки пропускной способности / сбоя кажется сломанной в Xcode 4.6

Реклама в приложении с помощью MonoTouch?

Корпоративное приложение не установлено в некоторых iPad на воздухе

UITextView в UITableView, Smooth Expand с помощью AutoLayout

Невозможно получить данные с использованием данных ядра

Несбалансированные вызовы UIViewController при запросе разрешений HealthKit

Просмотр в строке состояния в iPhone X симулятор искажен

PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.