0

Scenario: I have a UISlider that allows for values from 0 to 100. This slider will return a float such as 76.2345654234. In core data, I want to store this percentage as a double in this format: 0.76.

Problem: Using floor() or round() on the float gives me 76. Good. But if I divide by 100 now pesky trailing decimals show up. Sometimes certain numbers will work and give me 2 decimal places, but without fault, every time, another number won't and I'll end up with something that looks like this: 0.760000001.

No solution I've seen on this website or otherwise works 100% of the time. Surely there must be a way do to something this simple? Thanks!!

renldx
  • 13
  • 3
  • 1
    Does this answer your question? [Rounding a double value to x number of decimal places in swift](https://stackoverflow.com/questions/27338573/rounding-a-double-value-to-x-number-of-decimal-places-in-swift) – Joakim Danielson Dec 03 '19 at 18:59
  • 1
    I see now you have already linked to the question I linked to and reading the question again I think the problem is that you need to learn how floating point numbers work and that you sometimes has to expect very small differences in the value vs your expected value – Joakim Danielson Dec 03 '19 at 19:15
  • There isn't really such a thing as a "2 decimal place double". A Double is not a decimal, and Double(0.01) is not exactly 0.01. Have you tried using a Decimal type instead of a Float or Double? – John Lindgren Dec 03 '19 at 19:17
  • possible duplicate of https://stackoverflow.com/a/27705739/2303865 – Leo Dabus Dec 03 '19 at 19:33
  • Hi @JoakimDanielson I appreciate the help, but none of the linked solutions work consistently as pointed out in many comments that were either ignored or got told to accept it. If a solution doesn't work all the time, it doesn't work! If it can't be done that's fine, but that's not what those answers are saying, which is misleading. – renldx Dec 03 '19 at 20:17
  • Hey @JohnLindgren I'll try this tonight. Thanks for the suggestion! – renldx Dec 03 '19 at 20:29

2 Answers2

1

You said you want to store a number:

as a double

and

in this format: 0.76

You can't do both, you have to pick one. A Double is not a decimal, and it can't store most decimal numbers exactly. See this question:

Why can't decimal numbers be represented exactly in binary?

If you need to store decimal numbers exactly, use a different type than a Double: for example, the Decimal type). If for some reason you have to store your number as a Double, then you'll have to live with not storing decimal numbers exactly.

Side note: There are ways to round inexact Double values back to nearby decimals when you print them, but that's a different topic and not the question you asked.

John Lindgren
  • 777
  • 5
  • 14
  • Another very helpful answer. Thanks for helping me understand and not just brushing aside what I'm trying to do. At this point I'll either change to decimal or int as suggested above. I just wish I hadn't seen so many people suggest double for percentage values, it would of saved me lots of grief. – renldx Dec 03 '19 at 20:33
0

I want to store this percentage

Great. Store a percentage. That's an integer in your case, 76. Store that.

For all the gory details, see The Floating-Point Guide, but for your purposes, the answer is to store the value as an integer.

If you really want a decimal value, then you can set your type in Core Data to Decimal, and you'll get exactly what you want here, but I recommend using integers for two-significant-digit percentages. It's much more straight-forward.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • A result oriented answer! I appreciate that. The only reason I went with doubles is because, from my limited research, most people discussing the best data type for storing percentages seem to suggest double or decimal. But nobody has ever made the distinction between needing the fractional values or not, which is very helpful. I might go this route, thanks! – renldx Dec 03 '19 at 20:28
  • If you want an accurate representation of a real number, then Double is very good. If you want a value that maps precisely to a base-10 radix (i.e. "2 decimal digits"), then Double is very bad because it is base-2. So you need to pick what you want there. If you want two decimal digits, then you need something that works well with base-10, and that's not Double. If you want something that is quite precise to a large number of decimal places (but don't care if it maps to base 10), then Double is perfect. – Rob Napier Dec 03 '19 at 21:58