Ползунки - это основной элемент взаимодействия пользователя с моим приложением (см. Рисунок ...). Я использую их для записи процентных значений, которые затем сохраняются как Reading
s в моем хранилище базовых данных. Исходя из характера процентных значений, я бы сохранял их в виде десятичных значений от 0 до 1, а ползунки устанавливали диапазон от 0 до 1 и непрерывно запускал их действия, изменяющие значения. Когда мне нужно отобразить их, я извлекаю их из хранилища данных и отображаю их в виде типичных процентных значений, например, 67%
.
Теперь вот в чем загвоздка: свойство value
типа UISlider
имеет тип float
. Это означает, что я столкнусь с ошибками округления с самого начала. Мне не по вкусу точность, поэтому я надеюсь максимально снизить допустимый предел ошибок при работе с ними во всем приложении.
Какие есть варианты для управления процентными значениями, которые я считываю со своих слайдеров, сохраняю в Базовых данных и отображаю в остальной части моего приложения? Или, что еще лучше, какой из этих вариантов, которые я предложил, подойдет для моего приложения с точки зрения поддерживаемости кода , использования / производительности памяти и точности полученные значения ?
Использовать необработанные числа с плавающей запятой или двойные числа
На самом деле это ПЛОХО , очевидно из-за ошибок округления. Даже 0,64 превращается в 0,63 в какой-то момент времени (я проверил с моими ползунками, и они достигают много ). С разницей в 0,01 мое приложение определенно не переносит этого. Почему я даже пишу это как вариант?
Установите диапазон ползунка от 0 до 100, прочитайте их, округлите вверх / вниз и сохраните как целые числа
Это интересный выбор, поскольку я буду отображать только значения как ##%
, а не 0.##
. Мне не нужно выполнять арифметику с этими значениями, так что все выглядит хорошо:
// Recording and storing
// Slider range is 0 to 100
int percentage = (int) floor(slider.value); // Or ceil()
[reading setValue:[NSNumber numberWithInt:percentage]]; // Value is an integer
// Displaying
NSNumber *val = reading.value;
[readingLabel setText:[NSString stringWithFormat:@"%d%%", [val intValue]]];
Это не приведет к полному устранению ошибок округления, когда я впервые прочитаю их с моих ползунков (они все еще float
s!), Но, думаю, floor()
или ceil()
должны их сократить. Я не совсем уверен, хотя; может быть, кто-то здесь может дать более глубокое понимание, и именно поэтому я задаю этот вопрос.
Преобразовать и сохранить как NSDecimalNumber
объекты
Я взглянул на класс NSDecimalNumber
- проценты - это, в конце концов, факторы base-10 - но, учитывая, что он производит неизменяемые объекты, я не слишком уверен, что мне нравится идея писать длинные вызовы методов повсюду мой код многократно и создает повсеместно автоматически выпущенные объекты.
Даже создание NSDecimalNumber
из примитивов - это боль. В настоящее время я могу думать только об этом:
// Recording and storing
// Slider range is 0 to 1
NSDecimalNumber *decimalValue = [NSDecimalNumber decimalNumberWithString:
[NSString stringWithFormat:@"%0.2f",
slider.value]];
[reading setValue:decimalValue]; // Value is a decimal number
Умножение их на 100, поскольку я отображаю их как ##%
(как я уже говорил выше), также становится действительно утомительным и создает ненужные дополнительные объекты, которые затем преобразуются в NSString
s. Я бы продолжил, но я бы, вероятно, превратил этот пост в напыщенную речь, что определенно не то, ради чего я иду.
С учетом вышесказанного семантически NSDecimalNumber
должно иметь наибольшее значение, потому что, как я уже говорил выше, я считаю, что проценты должны храниться в виде десятичных значений от 0 до 1. Однако, глядя на то, как мое приложение работает с процентными значениями Я не знаю, выбрать ли умножить их на 100 и сохранить как целые числа или работать с NSDecimalNumber
.
Вы, наверное, видите, что я уже немного склоняюсь ко второму варианту (x100, используйте целые числа), потому что он просто удобнее и выглядит немного лучше для производительности. Тем не менее, я хотел бы узнать, считает ли кто-то третий вариант лучшим (более перспективным?).
Кстати, я не против изменить свою модель данных, чтобы изменить тип данных атрибута value
в моей сущности Reading
, и изменить существующий код, чтобы учесть изменения. Я пока не сделал слишком много, потому что остальное время проводил, волнуясь об этом.
Как вы думаете, на какой из вышеперечисленных вариантов я должен пойти?