2

I've been googling and trying to understand how things work with the Float values in swift, but can't seem to make any sense of it, I would really appreciate any help, I feel I'm just wasting my time.

For example, let's say that I have an API that returns some json data, I parse that data, make some calculations and then present some of the data to the user, something like this:

let balance : String = "773480.67"        // value that was received through json api
let commission : String = "100000.00"     // value that was received through json api

//framework maps the json properties
let floatBalance : Float = Float(balance)!     // at this point value is 773480.688
let floatCommission :  Float = Float(commission)!  //100000.0

//we do some math with the values
let result : Float = floatBalance + floatCommission    // this is somehow 873480.687

//and then show some of the values on a label
print("stringBalance: \(balance)")                     //stringBalance: 773480.67
print("floatBalance: \(floatBalance)")                 //floatBalance: 773481.0
print("floatCommission: \(floatCommission)")           //floatCommission: 100000.0
print("result: \(result)")                             //result: 873481.0
print("label: \(String(format:"%.2f", result))")       //label: 873480.69
print("just kill me now")

I'm using the EVReflection framework to map the json properties to an object, so the conversion from String to Float is done in the background without me doing much about it, but the values shown above are basically what I'm working with.

My question is, what do I need to do at the end to get the correct string (873480.67) from the resulting float (873480.687) or is my approach wrong from the start?

Thank you

Slavenko Miljic
  • 3,836
  • 2
  • 23
  • 36

1 Answers1

1

Actually floats can not represent numbers accurately, you'll have to use Double. Here is a very nice answer on that issue: https://stackoverflow.com/a/3730040/4662531

EDIT:

Sorry, but actually Double should not be use to perform calculations (I'm assuming from the naming of your variables you are working on some banking things). That part of the above linked answer is really giving a great suggestion:

A solution that works in just about any language is to use integers instead, and count cents. For instance, 1025 would be $10.25. Several languages also have built-in types to deal with money. Among others, Java has the BigDecimal class, and C# has the decimal type.

A colleague of mine that used to work in a banking company also confirmed that all calculations were done without using Floats or Double, but with Int as suggested in the link.

RomOne
  • 2,065
  • 17
  • 29
  • 2
    Well, that's just great, I wish I knew this before. I'm going to spend next 40 years just refactoring the existing code. – Slavenko Miljic Apr 17 '18 at 04:11
  • ahahah, had the exact same depression when I read that answer. All my code was based on floats... – RomOne Apr 17 '18 at 04:12
  • Doubles have more precision, but are not any more accurate than floats. – Avi Apr 17 '18 at 04:24
  • I can see the point in Integers, but currenty it would be a problem because of the way the received data is formatted. But the Double is more than precise enough, the numbers shown above, work just as I expect them to, when using Double. I've tried different numbers in hundreds of billions, and so far so good. I can live with one decimal off, every couple of trillions – Slavenko Miljic Apr 17 '18 at 05:24
  • yep fair enough. – RomOne Apr 17 '18 at 06:38
  • 1
    If you are strictly sure you will never get out of guaranteed precision of a chosen floating type (one shall think of 7 digits for single (float in C) and 16 digits for double), you can stay with floats, while keeping a proper care on operations. But these caring measures are cumbersome and expensive in many cases, so, using integers with assumed fixed point is better in general. – Netch Apr 17 '18 at 10:09