Math with NSNumbers and ints
Asked Answered
J

3

5

In objective-c I am trying to evaluate the following expression: _c = _f / 5 * 8; It tells me that an int and a NSNumber are invalid arguments to a binary expression.

Whats wrong? I am just getting started with objective-c and cocoa but am familiar with php and basic and kinda familiar with javascript.

Junno answered 27/3, 2012 at 11:52 Comment(2)
What kind of variables are _c and _f?Standfast
_c and _f are fahrenheit and celcius.(sorry if I didn't spell them correctly.)Junno
E
11

Objective-C has several different structures in place for you to use in calculations. From its C roots come the primitive numbers, ints, floats, doubles, etc, on which you can perform arithmetic operations directly (+, -, *, /, etc.). These are what you're looking to use.

On a higher lever, Objective-C also has NSNumber objects, which are simple wrappers for the primitive types listed above. They're used throughout Objective-C where primitives need to be stored (often within other objects such as arrays and dictionaries that don't take primitive values directly). Because NSNumbers are objects, you cannot perform direct arithmetic operations on them, you have to draw out their primitive values first (using intValue, for instance, to get an integer value, or doubleValue to get a double-precision floating point number). Because it's unclear what the variables represent in your question, I'm not going to venture a guess as to what it is you're trying to do (I don't want to mislead you), but you can find out more about NSNumber in the NSNumber Class Reference.

Finally, as Richard mentioned, there are NSDecimalNumbers. These are almost never used, since they're either simply not needed (they're designed to hold extremely high-precision numbers, far beyond the capacity of regular primitive values), or too complicated to use. They also have their own methods for performing arithmetic operations, and are generally irrelevant for everyday use. Again, if you're interested, look more into the NSDecimalNumber Class Reference.

For the most part, you're looking to use primitive numbers to do your calculations. When you need to store them, you can often 'box' and 'unbox' (store and retrieve) from NSNumber objects.

Each answered 27/3, 2012 at 12:22 Comment(2)
+1 but I would say that NSDecimalNumber is a great type to use for currency values.Canfield
@Canfield Yeah, but depending on the currencies you're dealing with and the operations you're performing, I'd even argue it's a better idea to represent your currency as simply integer multiples of your base value (e.g. store everything in terms of cents and not dollars) so you bypass any need for fractional amounts of money (which make little cents - er, sense). Of course, if you're doing percentages, or conversions, then yes, NSDecimalNumber is indeed a good choice.Each
S
5

You can't do these things with objects(NSNumber in this case). So you will have to take its' int/double/long/float value. I don't know which one is NSNumber, so here are 2 solutions, 1 will work:

_c = [_f doubleValue] / 5 * 8;

or:

_c = [NSNumber numberWithDouble:(_f / 5 * 8)];

Hope it helps

Shoop answered 27/3, 2012 at 11:55 Comment(0)
A
0

NSNumbers cannot have mathematical symbols applied to them. In your case, your code would actually look like this, using NSDecimalNumber instead (which has selectors to multiply and divide numbers):

NSDecimalNumber *_c = nil;
NSDecimalNumber *_f = [NSDecimalNumber decimalNumberWithString:@"7"];

_c = [[_f decimalNumberByDividingBy:[NSDecimalNumber decimalNumberWithString:@"5"]] decimalNumberByMultiplyingBy:[NSDecimalNumber decimalNumberWithString:@"8"]];

It's ugly, but it's how objective-c deals with numbers. Your other alternative is to get the doubleValues of each of your target numbers, and then multiplying them.

Actinometer answered 27/3, 2012 at 11:58 Comment(5)
This answer is misleading. NSDecimalNumbers aren't "how Objective-C deals with numbers", but rather a class used for computer very high-precision numbers. They're not meant to be used for simple math such as this; there's no reason to use them in this case above regular NSNumbers.Each
@ItaiFerber not true. One major advantage of using a NSDecimalNumber is it's precision, and even for small calculations as the one above, the overhead needed for the precision is very useful, and, it has the advantage of being put into an array over primitive types. Also don't forget that multiplication using NSNumber's -doubleValue is very lossy, and can lead to quite a bit of precision lost, e.g. 1/5 * 5 != 1, and you don't have to worry about integer to integer division too. The pros greatly outweigh the cons, that's why I choose NSDecimalNumberActinometer
While I agree with you that they do certainly have their advantages, I don't think they're worth it for simply multiplying something by 5/8 - that level of precision is normally not necessary or desirable. Again, I didn't down vote simply because you suggested using NSDecimalNumber (I find them fascinating, and would like to employ them more often), but simply because I think it's misleading to tell someone who doesn't yet know the difference that 'this is the way to do it'. See my answer for what I think.Each
Additionally, I don't like the fact that the easiest way to initialize an NSDecimalNumber is using a string - it promotes bad coding habits and styles. I certainly don't want to see people hard-coding numbers into strings of all things (magic numbers are bad enough!). Again, it's not meant for novices, but rather for people who know what they're doing and have a use for these; there's a reason they're not incredibly easy to use.Each
I could just store the values in floats(I'm trying to make a temperature converter program.)Junno

© 2022 - 2024 — McMap. All rights reserved.