Note that there are some explanatory texts on larger screens.

plurals
  1. POHow should I store percentage values in Core Data that are read off UISliders?
    primarykey
    data
    text
    <p>Sliders are my app's primary user interaction element (go figure...). I use them to record percentage values which are then stored as <code>Reading</code>s in my Core Data store. Based on the nature of percentage values, I would store them as decimal values between 0 and 1, and set the sliders to have a range from 0 to 1 and fire their value-changed actions continuously. When I need to display them I fetch them from the data store and display them as typical percentage values, e.g. <code>67%</code>.</p> <p>Now here's the catch: the <code>value</code> property of <code>UISlider</code> is of type <code>float</code>. That means I will run into rounding errors from the get-go. I'm nutty for accuracy, so I'm hoping to reduce the error margin as much as possible when I deal with them throughout my app.</p> <p>What options are there for managing the percentage values which I'm reading off my sliders, storing in Core Data and displaying in the rest of my app? Or better yet, which of these options that I've come up with would be best for my app in terms of <strong>code maintainability</strong>, <strong>memory usage/performance</strong> and <strong>accuracy of the values obtained</strong>?<br><br></p> <ol> <li><p><strong>Use raw floats or doubles</strong></p> <p>Actually this is <strong>BAD</strong>, obviously because of rounding errors. Even 0.64 turns into 0.63 at some point in time (I've tested with my sliders and these come up <em>a lot</em>). With a difference potentially as large as 0.01, my app is definitely intolerant of this. Why am I even writing this as an option anyway?<br><br></p></li> <li><p><strong>Set slider range to between 0 and 100, read them, round up/down and store as integers</strong></p> <p>This is an interesting choice given that I'll only ever display the values as <code>##%</code> and not <code>0.##</code>. I won't need to perform arithmetic on these values either, so doing this looks alright:</p> <pre><code>// 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]]]; </code></pre> <p>This is not going to completely take away the rounding errors when I first read them off my sliders (they're still <code>float</code>s!), but <code>floor()</code> or <code>ceil()</code> should cut it, I think. I'm not entirely certain though; maybe someone here can provide more insight, which is the point of me asking this question.<br><br></p></li> <li><p><strong>Convert to, and store as, <code>NSDecimalNumber</code> objects</strong></p> <p>I've taken a look at the <code>NSDecimalNumber</code> class — percentages are base-10 factors after all — but given that it produces immutable objects, I'm not too sure I like the idea of writing long method calls all over my code repeatedly and creating a crapton of autoreleased objects everywhere.</p> <p>Even creating <code>NSDecimalNumber</code>s out of primitives is a pain. Currently I can only think of doing this:</p> <pre><code>// 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 </code></pre> <p>Multiplying them by 100 since I display them as <code>##%</code> (like I said above) also gets really tedious and creates unnecessary extra objects which are then converted to <code>NSString</code>s. I would go on, but I'd likely turn this post into a rant which is definitely not what I'm going for.</p> <p>With that said, semantically <code>NSDecimalNumber</code> should make the most sense because, as I said above, I believe percentages are meant to be stored as decimal values between 0 and 1. However, looking at how my app works with percentage values, I don't know whether to choose multiplying them by 100 and storing as integers or working with <code>NSDecimalNumber</code>.<br><br></p></li> </ol> <p>You can probably see that I'm already leaning slightly toward the second option (x100, use integers) because it's just more convenient and looks to be slightly better for performance. However, I'd like to see if anyone thinks the third is a better (more future proof?) one.</p> <p>By the way, I don't mind modifying my data model to change the data type of the <code>value</code> attribute in my <code>Reading</code> entity, and modifying my existing code to accommodate the changes. I haven't done too much just yet because I've spent the rest of my time worrying about this.</p> <p>Which of the above options do you think I should go for?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload