How to store percentage values ​​in Core Data that are read from UISliders?

Sliders are the main element of interaction with my application (go figure ...). I use them to write percentage values, which are then saved as Reading in my master data store. Based on the nature of the percentage values, I would save them as decimal values ​​from 0 to 1 and set the sliders in the range from 0 to 1 and continuously float their changes that change the value. When I need to display them, I retrieve them from the data store and display them as typical percentages, for example. 67%

Now here's the catch: the value property of the UISlider is of type float . This means that I will encounter rounding errors from the very beginning. I turn up for accuracy, so I hope to minimize the margin of errors when I deal with them in my application.

What options are there to control the percentage that I read from the sliders stored in Core Data and displayed in the rest of my application? Or even better, which of these options that I came up with would be best for my application in terms of support , memory / performance usage, and accuracy of the values ​​obtained ?

  • Use unprocessed floats or double

    This is actually a BAD , obviously due to rounding errors. Even 0.64 at some point in time turns into 0.63 (I tested my sliders, and that is a lot). With a difference of potentially up to 0.01, my application is definitely intolerable. Why am I even writing this as an option?

  • Set the range of sliders in the range from 0 to 100, read them, round up / down and save as integers

    This is an interesting choice, given that I will only show ##% values, not 0.## . I also will not need to do arithmetic on these values, so this looks fine:

     // 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]]]; 

    This will not completely undo rounding errors when I first read them from my sliders (they are still float s!), But floor() or ceil() should trim it, I think. Although I'm not quite sure; maybe someone here can provide more understanding, and I want to ask this question.

  • Convert to and as <<2 → objects

    I looked at the NSDecimalNumber class - percentages are base-10 factors, after all, but given that it creates immutable objects, I'm not too sure that I like the idea of ​​writing long method calls all over my code repeatedly and creating a grootton of auto-implemented objects everywhere .

    Even creating NSDecimalNumber from primitives is a pain. Currently, I can only think about this:

     // 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 

    Multiplying them by 100, as I show them as ##% (as I said above) also becomes very tedious and creates unnecessary additional objects, which are then converted to NSString s. I would continue, but most likely this message turned into ranting, which is definitely not for me.

    With that said, semantically NSDecimalNumber should make the most sense, because, as I said above, I think that percentages should be stored as decimal values ​​from 0 to 1. However, looking at how my application works with percentage values, I don’t know whether to choose their multiplication by 100 and store as integers or work with NSDecimalNumber .

You can probably see that I'm already leaning a little in the second option (x100, use integers) because it is more convenient and looks a little better for performance. However, I would like to see if anyone thinks that the third is better (more than future proof?) One.

By the way, I do not mind modifying the data model to change the data type of the value attribute in my Reading entity and changing my existing code to make changes. I haven't done too much yet because I spent the rest of the time worrying about it.

Which of the above options do you think I should go for?

+4
source share
1 answer

If all you have to do is read from the slider, save the values ​​and represent them, dealing with primitive integers derived from a scaled, rounded float input of the slider, I would recommend. In any case, the slider does not exactly enter the input method, so your users will not notice if rounding the position of the slider is rounded.

I would use the same reasoning as when determining the number of significant digits from a calculation that takes real-world data as its input (for example, reading the temperature, etc.). It makes no sense to report a calculation of up to four significant digits if your original source has only two digits.

NSDecimals and NSDecimalNumbers are necessary if you want to do more advanced decimal calculations, but want to avoid floating point errors. For example, I use them when performing high-precision calculations in my application or if I need to somehow manipulate the currency. Of the two, I stick with NSDecimal for performance reasons , using NSDecimalNumber in cases where I need to interact with Core Data or need to import numeric values ​​into NSDecimal structs.

In this case, it seems that NSDecimal will be redundant, because you are in no way adjusting the values ​​of the slider just by displaying them on the screen. If you needed to perform the following manipulations (cutting in half, executing a formula, etc.), I would recommend rounding the slider to an integer representation by creating an NSDecimal structure, doing the calculations as NSDecimals, and then using the string output procedures for NSDecimal / NSDecimalNumber to display result on screen. Then you can easily save the calculated value as NSDecimalNumber in Core Data or as a string representation in SQLite or another file.

In addition, I would not worry too much about performance in simple computing, for example, until something like “Tools” tells you that this is a hot spot. Most likely, these calculations are with NSDecimal, etc. Will not.

+5
source

Source: https://habr.com/ru/post/1333223/


All Articles